/// <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); }
/// <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); }
/// <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));
/// <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);
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); }
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); } }