public static WebSocketMessage FromStream(WebSocketMessage msg, Stream stream) { byte[] header_proto = stream.ReadSafe(2); byte fin_rsv = (byte)((header_proto[0] & 0xF0) >> 4); byte opcode = (byte)(header_proto[0] & 0x0F); bool mask = (header_proto[1] & 0x80) == 0x80; ulong length = (ulong)(header_proto[1] & 0x7F); msg.Final = (fin_rsv & 0x08) == 0x08; msg.Opcode = (Opcode)opcode; msg.Masked = mask; if (fin_rsv != 0x08) { Log.Warn("Invalid fin_rsv!"); Log.Debug("\tfin and rsv: {0}", Convert.ToString(fin_rsv, 2)); Log.Debug("\topcode: {0}", opcode); Log.Debug("\tmask: {0}", mask ? 1 : 0); Log.Debug("\tlength: {0}", length); return(null); } #if EXTENDED_WEBSOCKET_DEBUG Log.Debug("Incoming packet:"); Log.Debug("\tfin and rsv: {0}", Convert.ToString(fin_rsv, 2)); Log.Debug("\topcode: {0}", opcode); Log.Debug("\tmask: {0}", mask ? 1 : 0); Log.Debug("\tlength: {0}", length); * / #endif if (length == 126) { length = BitConverter.ToUInt16(stream.ReadSafe(2, true), 0); #if EXTENDED_WEBSOCKET_DEBUG Log.Debug("Extended packet length(0-2^16): {0}", length); #endif } else if (length == 127) { length = BitConverter.ToUInt64(stream.ReadSafe(8, true), 0); #if EXTENDED_WEBSOCKET_DEBUG Log.Debug("Extended packet length(0-2^64): {0}", length); #endif } byte[] mask_key = new byte[4]; if (mask) { mask_key = stream.ReadSafe(4); #if EXTENDED_WEBSOCKET_DEBUG Log.Debug("Mask key is {0}", BitConverter.ToString(mask_key).Replace("-", "").ToLower()); #endif } msg.Mask = mask_key; if (length == 0) { msg.Payload = new byte[0]; return(msg); } byte[] buf = stream.ReadSafe((uint)length); if (mask) { buf = DecodeMask(buf, mask_key); } msg.Payload = buf; return(msg); }
public static WebSocketMessage FromStream(Stream stream) { WebSocketMessage ret = new WebSocketMessage(); return(FromStream(ret, stream)); }
public void SendText(string data) { Send(WebSocketMessage.Create(Encoding.UTF8.GetBytes(data), Opcode.Text, MaskOutgoing)); }
public void SendPing() { Send(WebSocketMessage.Create(new byte[0], Opcode.Ping, MaskOutgoing)); }
public void SendBinary(byte[] data) { Send(WebSocketMessage.SerializeInPlace(true, MaskOutgoing, Opcode.Binary, data, new byte[4])); }
public void Send(WebSocketMessage message) { byte[] buf = message.Serialize(); Send(buf); }
private void ReceiveLoop() { WebSocketMessage message = new WebSocketMessage(); while (Client.Connected && !Closed) { try { var result = WebSocketMessage.FromStream(message, NetworkStream); if (result == null) { Close(); return; } if (message.Final) { if (FragmentStart != null) { if (message.Opcode != Opcode.Continuation) { // control message } else { FragmentBuffer.Write(message.Payload, 0, message.Payload.Length); if (OnDataReceived != null) { OnDataReceived(this, FragmentStart, FragmentBuffer.ToArray()); } ReceiveQueue.Enqueue(FragmentBuffer.ToArray()); FragmentStart = null; FragmentBuffer.SetLength(0); } } else { switch (message.Opcode) { case Opcode.Binary: case Opcode.Text: ReceiveQueue.Enqueue(message.Payload); if (OnDataReceived != null) { OnDataReceived(this, message, message.Payload); } break; case Opcode.Ping: Send(WebSocketMessage.Create(message.Payload, Opcode.Pong, MaskOutgoing)); Log.Debug("Received ping"); break; case Opcode.Pong: Log.Debug("Received pong"); break; case Opcode.Close: Send(WebSocketMessage.Create(new byte[0], Opcode.Close, MaskOutgoing)); Close(); Log.Debug("Received WebSocket close, disconnected"); return; } } } else { if (FragmentStart == null) { // start receiving a fragment FragmentStart = message; FragmentBuffer.SetLength(0); FragmentBuffer.Write(message.Payload, 0, message.Payload.Length); } else { if (message.Opcode != Opcode.Continuation) { // illegal } else { FragmentBuffer.Write(message.Payload, 0, message.Payload.Length); } } } } catch (Exception ex) { Log.Error(ex); Close(); } } }