/// <summary> /// Parses the result of data read from the websocket. /// </summary> /// <param name="Result">The WebSocketReceiveResult.</param> /// <param name="ReadBuffer">The byte array buffer read from the socket stream.</param> private async Task ParseMessage(WebSocketReceiveResult Result, byte[] ReadBuffer) { if (!Result.EndOfMessage) { return; } RequestHistory.Add(DateTime.Now); while (RequestHistory.Count > 50) { RequestHistory.RemoveAt(0); } if (RequestHistory.Where(time => DateTime.Now - time < TimeSpan.FromSeconds(1)).Count() > 40) { await Player.WarnOrBan(this); } if (Result.MessageType == WebSocketMessageType.Text) { var trimmedString = Encoding.UTF8.GetString(TrimBytes(ReadBuffer)); var jsonMessage = JSON.Decode(trimmedString); StringMessageReceived?.Invoke(this, jsonMessage); } else if (Result.MessageType == WebSocketMessageType.Binary) { BinaryMessageReceived?.Invoke(this, TrimBytes(ReadBuffer)); } else if (Result.MessageType == WebSocketMessageType.Close) { SocketClosed?.Invoke(this, EventArgs.Empty); } }
private void Client_MessageReceived(object sender, byte[] e) { BinaryMessageReceived?.Invoke(sender, e); try { Message message = MessageManager.GetMessageFromBinary(e); MessageReceived?.Invoke(sender, new Tuple <Message, MessagePackSerializationException>(message, null)); } catch (MessagePackSerializationException exception) { MessageReceived?.Invoke(sender, new Tuple <Message, MessagePackSerializationException>(null, exception)); } }
protected async Task ProcessMessage() { var messages = await GetMessages().ConfigureAwait(false); if (messages is null) { return; } foreach (var message in messages) { switch (message.Code) { case WebSocketFrame.OpCode.ContinuationFrame: ContinuationFrameReceived?.Invoke(this, Encoding.UTF8.GetString(message.Data)); break; case WebSocketFrame.OpCode.TextFrame: if (message.Data.Length > 0) { MessageReceived?.Invoke(this, Encoding.UTF8.GetString(message.Data)); } break; case WebSocketFrame.OpCode.BinaryFrame: BinaryMessageReceived?.Invoke(this, message.Data); break; case WebSocketFrame.OpCode.ConnectionClose: TcpClient.Close(); var code = BitConverter.ToUInt16(message.Data.Take(2).Reverse().ToArray(), 0); ConnectionClosed?.Invoke(this, (WebSocketFrame.CloseStatusCode)code); break; case WebSocketFrame.OpCode.Ping: Ping?.Invoke(this, null); break; case WebSocketFrame.OpCode.Pong: Pong?.Invoke(this, null); break; default: Console.WriteLine("Not supported command."); break; } } }
private void MessageLoop() { var packet = new List <byte>(); var messageOpcode = 0x0; using (var messageBuffer = new MemoryStream()) { while (_client.Connected) { packet.Clear(); var ab = _client.Available; if (ab == 0) { continue; } packet.Add((byte)_clientStream.ReadByte()); var fin = (packet[0] & (1 << 7)) != 0; var rsv1 = (packet[0] & (1 << 6)) != 0; var rsv2 = (packet[0] & (1 << 5)) != 0; var rsv3 = (packet[0] & (1 << 4)) != 0; // Must error if is set. //if (rsv1 || rsv2 || rsv3) // return; var opcode = packet[0] & ((1 << 4) - 1); switch (opcode) { case 0x0: // Continuation Frame break; case 0x1: // Text case 0x2: // Binary case 0x8: // Connection Close messageOpcode = opcode; break; case 0x9: continue; // Ping case 0xA: continue; // Pong default: continue; // Reserved } packet.Add((byte)_clientStream.ReadByte()); var masked = IsMasking = (packet[1] & (1 << 7)) != 0; var pseudoLength = packet[1] - (masked ? 128 : 0); ulong actualLength = 0; if (pseudoLength > 0 && pseudoLength < 125) { actualLength = (ulong)pseudoLength; } else if (pseudoLength == 126) { var length = new byte[2]; _clientStream.Read(length, 0, length.Length); packet.AddRange(length); Array.Reverse(length); actualLength = BitConverter.ToUInt16(length, 0); } else if (pseudoLength == 127) { var length = new byte[8]; _clientStream.Read(length, 0, length.Length); packet.AddRange(length); Array.Reverse(length); actualLength = BitConverter.ToUInt64(length, 0); } var mask = new byte[4]; if (masked) { _clientStream.Read(mask, 0, mask.Length); packet.AddRange(mask); } if (actualLength > 0) { var data = new byte[actualLength]; _clientStream.Read(data, 0, data.Length); packet.AddRange(data); if (masked) { data = ApplyMask(data, mask); } messageBuffer.Write(data, 0, data.Length); } LogRequest?.Invoke(this, new LogEventArgs($@"RECV: {BitConverter.ToString(packet.ToArray())}")); if (!fin) { continue; } var message = messageBuffer.ToArray(); switch (messageOpcode) { case 0x1: AnyMessageReceived?.Invoke(this, message); TextMessageReceived?.Invoke(this, Encoding.UTF8.GetString(message)); break; case 0x2: AnyMessageReceived?.Invoke(this, message); BinaryMessageReceived?.Invoke(this, Encoding.UTF8.GetString(message)); break; case 0x8: Close(); break; default: throw new Exception("Invalid opcode: " + messageOpcode); } messageBuffer.SetLength(0); } } }
private void MessageLoop() { WebSocketSession session = this; TcpClient client = session.Client; Stream stream = session.ClientStream; List <byte> packet = new List <byte>(); int messageOpcode = 0x0; using (MemoryStream messageBuffer = new MemoryStream()) while (client.Connected) { packet.Clear(); int ab = client.Available; if (ab == 0) { continue; } packet.Add((byte)stream.ReadByte()); bool fin = (packet[0] & (1 << 7)) != 0; bool rsv1 = (packet[0] & (1 << 6)) != 0; bool rsv2 = (packet[0] & (1 << 5)) != 0; bool rsv3 = (packet[0] & (1 << 4)) != 0; // Must error if is set. //if (rsv1 || rsv2 || rsv3) // return; int opcode = packet[0] & ((1 << 4) - 1); switch (opcode) { case 0x0: // Continuation Frame break; case 0x1: // Text case 0x2: // Binary case 0x8: // Connection Close messageOpcode = opcode; break; case 0x9: continue; // Ping case 0xA: continue; // Pong default: continue; // Reserved } packet.Add((byte)stream.ReadByte()); bool masked = (packet[1] & (1 << 7)) != 0; int pseudoLength = packet[1] - (masked ? 128 : 0); ulong actualLength = 0; if (pseudoLength > 0 && pseudoLength < 125) { actualLength = (ulong)pseudoLength; } else if (pseudoLength == 126) { byte[] length = new byte[2]; stream.Read(length, 0, length.Length); packet.AddRange(length); Array.Reverse(length); actualLength = BitConverter.ToUInt16(length, 0); } else if (pseudoLength == 127) { byte[] length = new byte[8]; stream.Read(length, 0, length.Length); packet.AddRange(length); Array.Reverse(length); actualLength = BitConverter.ToUInt64(length, 0); } byte[] mask = new byte[4]; if (masked) { stream.Read(mask, 0, mask.Length); packet.AddRange(mask); } if (actualLength > 0) { byte[] data = new byte[actualLength]; stream.Read(data, 0, data.Length); packet.AddRange(data); if (masked) { data = ApplyMask(data, mask); } messageBuffer.Write(data, 0, data.Length); } Console.WriteLine($@"RECV: {BitConverter.ToString(packet.ToArray())}"); if (!fin) { continue; } byte[] message = messageBuffer.ToArray(); switch (messageOpcode) { case 0x1: AnyMessageReceived?.Invoke(session, message); TextMessageReceived?.Invoke(session, Encoding.UTF8.GetString(message)); break; case 0x2: AnyMessageReceived?.Invoke(session, message); BinaryMessageReceived?.Invoke(session, Encoding.UTF8.GetString(message)); break; case 0x8: Close(); break; default: throw new Exception("Invalid opcode: " + messageOpcode); } messageBuffer.SetLength(0); } }
private void WebSocket_BinaryReceived(object sender, byte[] e) { var raw = e; BinaryMessageReceived?.Invoke(this, raw); }
protected override void OnMessage(MessageEventArgs e) { base.OnMessage(e); BinaryMessageReceived?.Invoke(e.RawData); }