private async Task HandleClientMessage(ChannelHub.ConnectedClient cc, string command, string payload) { if (command == "ID") // Set client Id { cc.ClientId = payload; } else if (command == "JOIN") { await ChannelHub.AddClientToChannelAsync(cc, payload); } else if (command == "LEAVE") { ChannelHub.RemoveClientFromChannel(cc, payload); } else if (command == "MSG") { var messageData = System.Text.Json.JsonSerializer.Deserialize <ChannelHub.CommandMessageData>(payload); if (messageData != null) { ChannelHub.SendMessageFromClientToChannel(cc, messageData.Channel, messageData.Data); } } }
private async Task ProcessClientMessages(HttpContext context, WebSocket webSocket) { var cc = new ChannelHub.ConnectedClient() { WebSocketClient = webSocket, Channels = new List <string>(), ClientId = null, BufferedData = new List <byte>(), SendingData = false }; var message = await ReceiveFullMessage(webSocket, CancellationToken.None); WebSocketReceiveResult result = message.Item1; while (result != null && !result.CloseStatus.HasValue) { // Process message // Command syntax: Command|Length payload|Payload if (result.MessageType == WebSocketMessageType.Text) { var data = ASCIIEncoding.UTF8.GetString(message.Item2.ToArray()); var dataLeft = data.Length; while (dataLeft > 0) { var indexOfSeperator = data.IndexOf("|"); if (indexOfSeperator <= 0) { break; // No first separator } var command = data.Substring(0, indexOfSeperator); var indexOfSecondSeperator = data.IndexOf("|", indexOfSeperator + 1); if (indexOfSecondSeperator <= 0) { break; // No second separator } if (!Int32.TryParse(data.Substring(indexOfSeperator + 1, indexOfSecondSeperator - (indexOfSeperator + 1)), out var dataLength)) { break; // Message length is not a number } var indexEndOfMessage = dataLength + indexOfSeperator + 1; if (data.Length < indexEndOfMessage) { break; // Payload part is smaller than what the header is saying } await HandleClientMessage(cc, command, data.Substring(indexOfSecondSeperator + 1, dataLength)); data = data.Substring(indexEndOfMessage); } } message = await ReceiveFullMessage(webSocket, CancellationToken.None); result = message.Item1; } if (result == null) { await webSocket.CloseAsync(WebSocketCloseStatus.MessageTooBig, "Buffer full", CancellationToken.None); } else { await webSocket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None); } List <string> unsubChannels = null; lock (cc.Channels) unsubChannels = cc.Channels.ToList(); foreach (var channel in unsubChannels) { ChannelHub.RemoveClientFromChannel(cc, channel); } }