Ejemplo n.º 1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="socket"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        public override async Task ReceiveTextAsync(WebSocket socket, string data)
        {
            var item = JsonSerializer.Deserialize <WebSocketApiResult>(data);

            if (item == null)
            {
                item = new WebSocketApiResult(null, null)
                {
                    Status = -1, Message = "无效的信息"
                }
            }
            ;
            else if (item.Path.IsNullOrEmpty())
            {
                item.Path    = null;
                item.Message = ActionStatusMessage.WebsocketMessage.Sys.InvalidPath.Message;
                item.Status  = ActionStatusMessage.WebsocketMessage.Sys.InvalidPath.Status;
            }
            else
            {
                item.Message = ActionStatusMessage.WebsocketMessage.Sys.InvalidPath.Message;
                item.Status  = ActionStatusMessage.WebsocketMessage.Sys.InvalidPath.Status;
            }
            await SendMessageAsync(base.WebSocketConnectionManager.GetId(socket), item);
        }
Ejemplo n.º 2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="socket"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        public override async Task ReceiveBinaryAsync(WebSocket socket, byte[] data)
        {
            var content = new
            {
                id = Guid.NewGuid()
            };

            var item = new WebSocketApiResult(null, JsonSerializer.Serialize(content))
            {
            };

            await SendMessageAsync(base.WebSocketConnectionManager.GetId(socket), item);
        }
Ejemplo n.º 3
0
 /// <summary>
 /// 发送消息给单个连接
 /// </summary>
 /// <param name="socket"></param>
 /// <param name="item"></param>
 /// <returns></returns>
 public async Task SendMessageAsync(WebSocketConnection socket, WebSocketApiResult item) => await SendMessageAsync(socket, JsonSerializer.Serialize(item));
Ejemplo n.º 4
0
 /// <summary>
 /// 发送信息给单个用户
 /// </summary>
 /// <param name="userid"></param>
 /// <param name="item"></param>
 /// <returns></returns>
 public async Task SendMessageAsync(string userid, WebSocketApiResult item) => await SendMessageAsync(WebSocketConnectionManager.GetSocketById(userid), item);
Ejemplo n.º 5
0
        public async Task <WebSocketCloseStatus> Run(CancellationToken token)
        {
            WebSocketApiResult apiObjectResult =
                await _socket.ReceiveApiMessage(_buffer, token);

            while (!apiObjectResult.SocketResult.CloseStatus.HasValue && !token.IsCancellationRequested)
            {
                if (apiObjectResult.Obj == null)
                {
                    await _socket.SendJson(
                        SharedJsonApiObjectFactory.CreateError(apiObjectResult.JsonException.Message), token);
                }
                else
                {
                    switch (apiObjectResult.Obj.context)
                    {
                    case JsonApiContextTypes.server:
                        if (!(await HandleSharedMessage(apiObjectResult.Obj, token)))
                        {
                            switch (Device)
                            {
                            case Host _:
                                await HandleHostMessage(apiObjectResult.Obj, token);

                                break;

                            case Peripheral _:
                                await HandlePeripheralMessage(apiObjectResult.Obj, token);

                                break;
                            }
                        }
                        break;

                    case JsonApiContextTypes.device:
                        if (_partner != null)
                        {
                            _partner?.PartnerSendMessage(apiObjectResult.Obj);
                        }
                        else
                        {
                            await _socket.SendJson(
                                SharedJsonApiObjectFactory.CreateError(
                                    "You don't have a partner, annoy somebody else >.>"));
                        }
                        break;
                    }
                }
                try
                {
                    apiObjectResult = await _socket.ReceiveApiMessage(_buffer, token);
                }
                catch (WebSocketException wse)
                {
                    _logger.LogWarning(wse, "WebSocketException occured while receiving message.");
                    apiObjectResult = new WebSocketApiResult();
                    apiObjectResult.SocketResult = new WebSocketReceiveResult(0, WebSocketMessageType.Binary, true, WebSocketCloseStatus.Empty, "WebSocketException thrown while receiving message.");
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, "Error handling request.");
                    apiObjectResult = new WebSocketApiResult();
                    apiObjectResult.SocketResult = new WebSocketReceiveResult(0, WebSocketMessageType.Binary, true, WebSocketCloseStatus.InternalServerError, "Exception thrown while receiving message.");
                }
            }
            return(apiObjectResult.SocketResult.CloseStatus ?? WebSocketCloseStatus.NormalClosure);
        }
Ejemplo n.º 6
0
        private async Task HandleWebSocket(HttpContext ctx, AnperiDbContext dbContext)
        {
            WebSocket socket = await ctx.WebSockets.AcceptWebSocketAsync();

            var buffer = new byte[_options.Value.WsBufferSize];

            WebSocketApiResult apiObjectResult =
                await socket.ReceiveApiMessage(buffer, _options.Value.RequestCancelToken);

            bool authFailed = true;
            WebSocketCloseStatus closeStatus = WebSocketCloseStatus.Empty;

            if (apiObjectResult.Obj == null)
            {
                await socket.SendJson(
                    SharedJsonApiObjectFactory.CreateError(apiObjectResult.JsonException.Message),
                    _options.Value.RequestCancelToken);
            }
            else
            {
                if (apiObjectResult.Obj.context == JsonApiContextTypes.server &&
                    apiObjectResult.Obj.message_type == JsonApiMessageTypes.request)
                {
                    apiObjectResult.Obj.data.TryGetValue(nameof(JsonLoginData.device_type), out string typeString);
                    if (Enum.TryParse(typeString, out SharedJsonDeviceType type) &&
                        Enum.TryParse(apiObjectResult.Obj.message_code, out SharedJsonRequestCode code))
                    {
                        RegisteredDevice device = null;
                        switch (code)
                        {
                        case SharedJsonRequestCode.login:
                            if (!apiObjectResult.Obj.data.TryGetValue("token", out string token))
                            {
                                await socket.SendJson(
                                    SharedJsonApiObjectFactory.CreateError("Error retrieving token from request."));
                            }
                            else
                            {
                                switch (type)
                                {
                                case SharedJsonDeviceType.host:
                                    device = dbContext.Hosts.SingleOrDefault(d => d.Token == token);
                                    break;

                                case SharedJsonDeviceType.peripheral:
                                    device = dbContext.Peripherals.SingleOrDefault(d => d.Token == token);
                                    break;

                                default:
                                    await socket.SendJson(
                                        SharedJsonApiObjectFactory.CreateError(
                                            "You need to be a host or peripheral."));

                                    break;
                                }
                                if (device != null)
                                {
                                    AuthenticatedWebSocketConnection activeConn;
                                    lock (_activeConnections)
                                    {
                                        _activeConnections.TryGetValue(device.Id, out activeConn);
                                    }
                                    if (activeConn != null)
                                    {
                                        activeConn.Abort();
                                        await RemoveLoggedInDevice(activeConn, dbContext);
                                    }
                                    closeStatus = await LoginDevice(ctx, socket, buffer, device, dbContext);

                                    authFailed = false;
                                }
                            }
                            break;

                        case SharedJsonRequestCode.register:
                            switch (type)
                            {
                            case SharedJsonDeviceType.host:
                                device = new Host();
                                break;

                            case SharedJsonDeviceType.peripheral:
                                device = new Peripheral();
                                break;

                            default:
                                await socket.SendJson(
                                    SharedJsonApiObjectFactory.CreateError(
                                        "You need to be a host or peripheral."));

                                break;
                            }
                            if (device != null)
                            {
                                device.Token = Cryptography.CreateAuthToken();
                                if (apiObjectResult.Obj.data.TryGetValue("name", out string name))
                                {
                                    device.Name = name;
                                }
                                else
                                {
                                    await socket.SendJson(
                                        SharedJsonApiObjectFactory.CreateError(
                                            "A device registration requires a name!"));
                                }
                                if (string.IsNullOrWhiteSpace(device.Name))
                                {
                                    device.Name = "devices want a name :(";
                                }
                                dbContext.RegisteredDevices.Add(device);
                                await dbContext.SaveChangesAsync();

                                await socket.SendJson(
                                    SharedJsonApiObjectFactory.CreateRegisterResponse(device.Token, device.Name));

                                closeStatus = await LoginDevice(ctx, socket, buffer, device, dbContext);

                                authFailed = false;
                            }
                            break;

                        default:
                            await socket.SendJson(
                                SharedJsonApiObjectFactory.CreateError("Only login and register are valid here."));

                            break;
                        }
                    }
                    else
                    {
                        await socket.SendJson(
                            SharedJsonApiObjectFactory.CreateError(
                                "Error parsing correct login or register parameters."));
                    }
                }
            }

            if (authFailed)
            {
                await socket.SendJson(SharedJsonApiObjectFactory.CreateLoginResponse(false, null));

                CancellationTokenSource cts = new CancellationTokenSource(TimeSpan.FromMilliseconds(1000));
                await socket.CloseAsync(WebSocketCloseStatus.PolicyViolation, "Authentication failed.", cts.Token);
            }
            else if (_options.Value.RequestCancelToken.IsCancellationRequested)
            {
                CancellationTokenSource cts = new CancellationTokenSource(TimeSpan.FromMilliseconds(1000));
                await socket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Server is shutting down.", cts.Token);
            }
            else
            {
                await socket.CloseAsync(closeStatus, apiObjectResult.SocketResult.CloseStatusDescription, CancellationToken.None);
            }
        }