Exemple #1
0
        /// <summary>
        /// Closes the websocket connection.   Sends a close message to the other side if it hasn't already done so.
        /// </summary>
        /// <param name="message"></param>
        public void Close(string message)
        {
            if (_initialMsgTimeout > 0)
            {
                _receiveDone.Set();
                _initialMsgTimeout = 0;
            }
            if (_networkContext == null)
            {
                return;
            }
            if (_networkContext.Stream != null)
            {
                if (_networkContext.Stream.CanWrite)
                {
                    byte[]         messagedata        = Encoding.UTF8.GetBytes(message);
                    WebSocketFrame closeResponseFrame = new WebSocketFrame()
                    {
                        Header           = WebsocketFrameHeader.HeaderDefault(),
                        WebSocketPayload = messagedata
                    };
                    closeResponseFrame.Header.Opcode     = WebSocketReader.OpCode.Close;
                    closeResponseFrame.Header.PayloadLen = (ulong)messagedata.Length;
                    closeResponseFrame.Header.IsEnd      = true;
                    SendSocket(closeResponseFrame.ToBytes());
                }
            }
            CloseDelegate closeD = OnClose;

            if (closeD != null)
            {
                closeD(this, new CloseEventArgs());
            }

            _closing = true;
        }
        /// <summary>
        /// Processes a websocket frame and triggers consumer events
        /// </summary>
        /// <param name="psocketState">We need to modify the websocket state here depending on the frame</param>
        private void ProcessFrame(WebSocketState psocketState)
        {
            if (psocketState.Header.IsMasked)
            {
                byte[] unmask = psocketState.ReceivedBytes.ToArray();
                WebSocketReader.Mask(psocketState.Header.Mask, unmask);
                psocketState.ReceivedBytes = new List<byte>(unmask);
            }
            if (psocketState.Header.Opcode != WebSocketReader.OpCode.Continue  && _initialMsgTimeout > 0)
            {
                _receiveDone.Set();
                _initialMsgTimeout = 0;
            }
            switch (psocketState.Header.Opcode)
            {
                case WebSocketReader.OpCode.Ping:
                    PingDelegate pingD = OnPing;
                    if (pingD != null)
                    {
                        pingD(this, new PingEventArgs());
                    }

                    WebSocketFrame pongFrame = new WebSocketFrame(){Header = WebsocketFrameHeader.HeaderDefault(),WebSocketPayload = new byte[0]};
                    pongFrame.Header.Opcode = WebSocketReader.OpCode.Pong;
                    pongFrame.Header.IsEnd = true;
                    SendSocket(pongFrame.ToBytes());
                    break;
                case WebSocketReader.OpCode.Pong:
                 
                    PongDelegate pongD = OnPong;
                    if (pongD != null)
                    {
                        pongD(this, new PongEventArgs(){PingResponseMS = Util.EnvironmentTickCountSubtract(Util.EnvironmentTickCount(),_pingtime)});
                    }
                    break;
                case WebSocketReader.OpCode.Binary:
                    if (!psocketState.Header.IsEnd) // Not done, so we need to store this and wait for the end frame.
                    {
                        psocketState.ContinuationFrame = new WebSocketFrame
                                                             {
                                                                 Header = psocketState.Header,
                                                                 WebSocketPayload =
                                                                     psocketState.ReceivedBytes.ToArray()
                                                             };
                    }
                    else
                    {
                        // Send Done Event!
                        DataDelegate dataD = OnData;
                        if (dataD != null)
                        {
                            dataD(this,new WebsocketDataEventArgs(){Data = psocketState.ReceivedBytes.ToArray()});
                        }
                    }
                    break;
                case WebSocketReader.OpCode.Text:
                    if (!psocketState.Header.IsEnd) // Not done, so we need to store this and wait for the end frame.
                    {
                        psocketState.ContinuationFrame = new WebSocketFrame
                                                             {
                                                                 Header = psocketState.Header,
                                                                 WebSocketPayload =
                                                                     psocketState.ReceivedBytes.ToArray()
                                                             };
                    }
                    else
                    {
                        TextDelegate textD = OnText;
                        if (textD != null)
                        {
                            textD(this, new WebsocketTextEventArgs() { Data = Encoding.UTF8.GetString(psocketState.ReceivedBytes.ToArray()) });
                        }
                        
                        // Send Done Event!
                    }
                    break;
                case WebSocketReader.OpCode.Continue:  // Continuation.  Multiple frames worth of data for one message.   Only valid when not using Control Opcodes
                    //Console.WriteLine("currhead " + psocketState.Header.IsEnd);
                    //Console.WriteLine("Continuation! " + psocketState.ContinuationFrame.Header.IsEnd);
                    byte[] combineddata = new byte[psocketState.ReceivedBytes.Count+psocketState.ContinuationFrame.WebSocketPayload.Length];
                    byte[] newdata = psocketState.ReceivedBytes.ToArray();
                    Buffer.BlockCopy(psocketState.ContinuationFrame.WebSocketPayload, 0, combineddata, 0, psocketState.ContinuationFrame.WebSocketPayload.Length);
                    Buffer.BlockCopy(newdata, 0, combineddata,
                                        psocketState.ContinuationFrame.WebSocketPayload.Length, newdata.Length);
                    psocketState.ContinuationFrame.WebSocketPayload = combineddata;
                    psocketState.Header.PayloadLen = (ulong)combineddata.Length;
                    if (psocketState.Header.IsEnd)
                    {
                        if (psocketState.ContinuationFrame.Header.Opcode == WebSocketReader.OpCode.Text)
                        {
                            // Send Done event    
                            TextDelegate textD = OnText;
                            if (textD != null)
                            {
                                textD(this, new WebsocketTextEventArgs() { Data = Encoding.UTF8.GetString(combineddata) });
                            }
                        }
                        else if (psocketState.ContinuationFrame.Header.Opcode == WebSocketReader.OpCode.Binary)
                        {
                            // Send Done event
                            DataDelegate dataD = OnData;
                            if (dataD != null)
                            {
                                dataD(this, new WebsocketDataEventArgs() { Data = combineddata });
                            }
                        }
                        else
                        {
                            // protocol violation
                        }
                        psocketState.ContinuationFrame = null;
                    }
                    break;
                case WebSocketReader.OpCode.Close:
                    Close(string.Empty);
                    
                    break;
               
            }
            psocketState.Header.SetDefault();
            psocketState.ReceivedBytes.Clear();
            psocketState.ExpectedBytes = 0;
        }
        /// <summary>
        /// Closes the websocket connection.   Sends a close message to the other side if it hasn't already done so.
        /// </summary>
        /// <param name="message"></param>
        public void Close(string message)
        {
            if (_initialMsgTimeout > 0)
            {
                _receiveDone.Set();
                _initialMsgTimeout = 0;
            }
            if (_networkContext == null)
                return;
            if (_networkContext.Stream != null)
            {
                if (_networkContext.Stream.CanWrite)
            {
                byte[] messagedata = Encoding.UTF8.GetBytes(message);
                WebSocketFrame closeResponseFrame = new WebSocketFrame()
                                                        {
                                                            Header = WebsocketFrameHeader.HeaderDefault(),
                                                            WebSocketPayload = messagedata
                                                        };
                closeResponseFrame.Header.Opcode = WebSocketReader.OpCode.Close;
                closeResponseFrame.Header.PayloadLen = (ulong) messagedata.Length;
                closeResponseFrame.Header.IsEnd = true;
                SendSocket(closeResponseFrame.ToBytes());
            }
                }
            CloseDelegate closeD = OnClose;
            if (closeD != null)
            {
                closeD(this, new CloseEventArgs());
            }

            _closing = true;
        }
 /// <summary>
 /// Sends a Ping check to the other side.  The other side SHOULD respond as soon as possible with a pong frame.   This interleaves with incoming fragmented frames.
 /// </summary>
 public void SendPingCheck()
 {
     if (_initialMsgTimeout > 0)
     {
         _receiveDone.Set();
         _initialMsgTimeout = 0;
     }
     WebSocketFrame pingFrame = new WebSocketFrame() { Header = WebsocketFrameHeader.HeaderDefault(), WebSocketPayload = new byte[0] };
     pingFrame.Header.Opcode = WebSocketReader.OpCode.Ping;
     pingFrame.Header.IsEnd = true;
     _pingtime = Util.EnvironmentTickCount();
     SendSocket(pingFrame.ToBytes());
 }
        public void SendData(byte[] data)
        {
            if (_initialMsgTimeout > 0)
            {
                _receiveDone.Set();
                _initialMsgTimeout = 0;
            }
            WebSocketFrame dataMessageFrame = new WebSocketFrame() { Header = WebsocketFrameHeader.HeaderDefault(), WebSocketPayload = data};
            dataMessageFrame.Header.IsEnd = true;
            dataMessageFrame.Header.Opcode = WebSocketReader.OpCode.Binary;
            SendSocket(dataMessageFrame.ToBytes());

        }
 /// <summary>
 /// Sends a string to the other side
 /// </summary>
 /// <param name="message">the string message that is to be sent</param>
 public void SendMessage(string message)
 {
     if (_initialMsgTimeout > 0)
     {
         _receiveDone.Set();
         _initialMsgTimeout = 0;
     }
     byte[] messagedata = Encoding.UTF8.GetBytes(message);
     WebSocketFrame textMessageFrame = new WebSocketFrame() { Header = WebsocketFrameHeader.HeaderDefault(), WebSocketPayload = messagedata };
     textMessageFrame.Header.Opcode = WebSocketReader.OpCode.Text;
     textMessageFrame.Header.IsEnd = true;
     SendSocket(textMessageFrame.ToBytes());
     
 }
        /// <summary>
        /// Processes a websocket frame and triggers consumer events
        /// </summary>
        /// <param name="psocketState">We need to modify the websocket state here depending on the frame</param>
        private void ProcessFrame(WebSocketState psocketState)
        {
            if (psocketState.Header.IsMasked)
            {
                byte[] unmask = psocketState.ReceivedBytes.ToArray();
                WebSocketReader.Mask(psocketState.Header.Mask, unmask);
                psocketState.ReceivedBytes = new List <byte>(unmask);
            }

            switch (psocketState.Header.Opcode)
            {
            case WebSocketReader.OpCode.Ping:
                PingDelegate pingD = OnPing;
                if (pingD != null)
                {
                    pingD(this, new PingEventArgs());
                }

                WebSocketFrame pongFrame = new WebSocketFrame()
                {
                    Header = WebsocketFrameHeader.HeaderDefault(), WebSocketPayload = new byte[0]
                };
                pongFrame.Header.Opcode = WebSocketReader.OpCode.Pong;
                pongFrame.Header.IsEnd  = true;
                SendSocket(pongFrame.ToBytes());
                break;

            case WebSocketReader.OpCode.Pong:

                PongDelegate pongD = OnPong;
                if (pongD != null)
                {
                    pongD(this, new PongEventArgs()
                    {
                        PingResponseMS = Util.EnvironmentTickCountSubtract(Util.EnvironmentTickCount(), _pingtime)
                    });
                }
                break;

            case WebSocketReader.OpCode.Binary:
                if (!psocketState.Header.IsEnd)     // Not done, so we need to store this and wait for the end frame.
                {
                    psocketState.ContinuationFrame = new WebSocketFrame
                    {
                        Header           = psocketState.Header,
                        WebSocketPayload =
                            psocketState.ReceivedBytes.ToArray()
                    };
                }
                else
                {
                    // Send Done Event!
                    DataDelegate dataD = OnData;
                    if (dataD != null)
                    {
                        dataD(this, new WebsocketDataEventArgs()
                        {
                            Data = psocketState.ReceivedBytes.ToArray()
                        });
                    }
                }
                break;

            case WebSocketReader.OpCode.Text:
                if (!psocketState.Header.IsEnd)     // Not done, so we need to store this and wait for the end frame.
                {
                    psocketState.ContinuationFrame = new WebSocketFrame
                    {
                        Header           = psocketState.Header,
                        WebSocketPayload =
                            psocketState.ReceivedBytes.ToArray()
                    };
                }
                else
                {
                    TextDelegate textD = OnText;
                    if (textD != null)
                    {
                        textD(this, new WebsocketTextEventArgs()
                        {
                            Data = Encoding.UTF8.GetString(psocketState.ReceivedBytes.ToArray())
                        });
                    }

                    // Send Done Event!
                }
                break;

            case WebSocketReader.OpCode.Continue:      // Continuation.  Multiple frames worth of data for one message.   Only valid when not using Control Opcodes
                //Console.WriteLine("currhead " + psocketState.Header.IsEnd);
                //Console.WriteLine("Continuation! " + psocketState.ContinuationFrame.Header.IsEnd);
                byte[] combineddata = new byte[psocketState.ReceivedBytes.Count + psocketState.ContinuationFrame.WebSocketPayload.Length];
                byte[] newdata      = psocketState.ReceivedBytes.ToArray();
                Buffer.BlockCopy(psocketState.ContinuationFrame.WebSocketPayload, 0, combineddata, 0, psocketState.ContinuationFrame.WebSocketPayload.Length);
                Buffer.BlockCopy(newdata, 0, combineddata,
                                 psocketState.ContinuationFrame.WebSocketPayload.Length, newdata.Length);
                psocketState.ContinuationFrame.WebSocketPayload = combineddata;
                psocketState.Header.PayloadLen = (ulong)combineddata.Length;
                if (psocketState.Header.IsEnd)
                {
                    if (psocketState.ContinuationFrame.Header.Opcode == WebSocketReader.OpCode.Text)
                    {
                        // Send Done event
                        TextDelegate textD = OnText;
                        if (textD != null)
                        {
                            textD(this, new WebsocketTextEventArgs()
                            {
                                Data = Encoding.UTF8.GetString(combineddata)
                            });
                        }
                    }
                    else if (psocketState.ContinuationFrame.Header.Opcode == WebSocketReader.OpCode.Binary)
                    {
                        // Send Done event
                        DataDelegate dataD = OnData;
                        if (dataD != null)
                        {
                            dataD(this, new WebsocketDataEventArgs()
                            {
                                Data = combineddata
                            });
                        }
                    }
                    else
                    {
                        // protocol violation
                    }
                    psocketState.ContinuationFrame = null;
                }
                break;

            case WebSocketReader.OpCode.Close:
                Close(string.Empty);

                break;
            }
            psocketState.Header.SetDefault();
            psocketState.ReceivedBytes.Clear();
            psocketState.ExpectedBytes = 0;
        }
 /// <summary>
 /// Sends a Ping check to the other side.  The other side SHOULD respond as soon as possible with a pong frame.   This interleaves with incoming fragmented frames.
 /// </summary>
 public void SendPingCheck()
 {
     WebSocketFrame pingFrame = new WebSocketFrame() { Header = WebsocketFrameHeader.HeaderDefault(), WebSocketPayload = new byte[0] };
     pingFrame.Header.Opcode = WebSocketReader.OpCode.Ping;
     pingFrame.Header.IsEnd = true;
     _pingtime = Util.EnvironmentTickCount();
     SendSocket(pingFrame.ToBytes());
 }
        public void SendData(byte[] data)
        {
            WebSocketFrame dataMessageFrame = new WebSocketFrame() { Header = WebsocketFrameHeader.HeaderDefault(), WebSocketPayload = data};
            dataMessageFrame.Header.IsEnd = true;
            dataMessageFrame.Header.Opcode = WebSocketReader.OpCode.Binary;
            SendSocket(dataMessageFrame.ToBytes());

        }
 /// <summary>
 /// Sends a string to the other side
 /// </summary>
 /// <param name="message">the string message that is to be sent</param>
 public void SendMessage(string message)
 {
     byte[] messagedata = Encoding.UTF8.GetBytes(message);
     WebSocketFrame textMessageFrame = new WebSocketFrame() { Header = WebsocketFrameHeader.HeaderDefault(), WebSocketPayload = messagedata };
     textMessageFrame.Header.Opcode = WebSocketReader.OpCode.Text;
     textMessageFrame.Header.IsEnd = true;
     SendSocket(textMessageFrame.ToBytes());
     
 }