예제 #1
0
        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);
        }
예제 #2
0
        public static WebSocketMessage FromStream(Stream stream)
        {
            WebSocketMessage ret = new WebSocketMessage();

            return(FromStream(ret, stream));
        }
예제 #3
0
 public void SendText(string data)
 {
     Send(WebSocketMessage.Create(Encoding.UTF8.GetBytes(data), Opcode.Text, MaskOutgoing));
 }
예제 #4
0
 public void SendPing()
 {
     Send(WebSocketMessage.Create(new byte[0], Opcode.Ping, MaskOutgoing));
 }
예제 #5
0
 public void SendBinary(byte[] data)
 {
     Send(WebSocketMessage.SerializeInPlace(true, MaskOutgoing, Opcode.Binary, data, new byte[4]));
 }
예제 #6
0
 public void Send(WebSocketMessage message)
 {
     byte[] buf = message.Serialize();
     Send(buf);
 }
예제 #7
0
        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();
                }
            }
        }