Beispiel #1
0
        /// <summary>
        /// Clear WebSocket send/receive buffers
        /// </summary>
        public void ClearWsBuffers()
        {
            lock (WsReceiveLock)
            {
                WsReceived    = false;
                WsHeaderSize  = 0;
                WsPayloadSize = 0;
                WsReceiveBuffer.Clear();
                Array.Clear(WsReceiveMask, 0, WsReceiveMask.Length);
            }

            lock (WsSendLock)
            {
                WsSendBuffer.Clear();
                Array.Clear(WsSendMask, 0, WsSendMask.Length);
            }
        }
Beispiel #2
0
        /// <summary>
        /// Prepare WebSocket send frame
        /// </summary>
        /// <param name="buffer">Buffer to send</param>
        /// <param name="offset">Buffer offset</param>
        /// <param name="size">Buffer size</param>
        public void PrepareReceiveFrame(byte[] buffer, long offset, long size)
        {
            lock (WsReceiveLock)
            {
                var index = 0;

                // Clear received data after WebSocket frame was processed
                if (WsReceived)
                {
                    WsReceived    = false;
                    WsHeaderSize  = 0;
                    WsPayloadSize = 0;
                    WsReceiveBuffer.Clear();
                    Array.Clear(WsReceiveMask, 0, WsReceiveMask.Length);
                }

                while (size > 0)
                {
                    // Clear received data after WebSocket frame was processed
                    if (WsReceived)
                    {
                        WsReceived    = false;
                        WsHeaderSize  = 0;
                        WsPayloadSize = 0;
                        WsReceiveBuffer.Clear();
                        Array.Clear(WsReceiveMask, 0, WsReceiveMask.Length);
                    }

                    // Prepare WebSocket frame opcode and mask flag
                    if (WsReceiveBuffer.Count < 2)
                    {
                        for (int i = 0; i < 2; ++i, ++index, --size)
                        {
                            if (size == 0)
                            {
                                return;
                            }
                            WsReceiveBuffer.Add(buffer[offset + index]);
                        }
                    }

                    byte opcode  = (byte)(WsReceiveBuffer[0] & 0x0F);
                    bool fin     = ((WsReceiveBuffer[0] >> 7) & 0x01) != 0;
                    bool mask    = ((WsReceiveBuffer[1] >> 7) & 0x01) != 0;
                    int  payload = WsReceiveBuffer[1] & (~0x80);

                    // Prepare WebSocket frame size
                    if (payload <= 125)
                    {
                        WsHeaderSize             = 2 + (mask ? 4 : 0);
                        WsPayloadSize            = payload;
                        WsReceiveBuffer.Capacity = WsHeaderSize + WsPayloadSize;
                    }
                    else if (payload == 126)
                    {
                        if (WsReceiveBuffer.Count < 4)
                        {
                            for (int i = 0; i < 2; ++i, ++index, --size)
                            {
                                if (size == 0)
                                {
                                    return;
                                }
                                WsReceiveBuffer.Add(buffer[offset + index]);
                            }
                        }

                        payload                  = ((WsReceiveBuffer[2] << 8) | (WsReceiveBuffer[3] << 0));
                        WsHeaderSize             = 4 + (mask ? 4 : 0);
                        WsPayloadSize            = payload;
                        WsReceiveBuffer.Capacity = WsHeaderSize + WsPayloadSize;
                    }
                    else if (payload == 127)
                    {
                        if (WsReceiveBuffer.Count < 10)
                        {
                            for (int i = 0; i < 8; ++i, ++index, --size)
                            {
                                if (size == 0)
                                {
                                    return;
                                }
                                WsReceiveBuffer.Add(buffer[offset + index]);
                            }
                        }

                        payload                  = ((WsReceiveBuffer[2] << 56) | (WsReceiveBuffer[3] << 48) | (WsReceiveBuffer[4] << 40) | (WsReceiveBuffer[5] << 32) | (WsReceiveBuffer[6] << 24) | (WsReceiveBuffer[7] << 16) | (WsReceiveBuffer[8] << 8) | (WsReceiveBuffer[9] << 0));
                        WsHeaderSize             = 10 + (mask ? 4 : 0);
                        WsPayloadSize            = payload;
                        WsReceiveBuffer.Capacity = WsHeaderSize + WsPayloadSize;
                    }

                    // Prepare WebSocket frame mask
                    if (mask)
                    {
                        if (WsReceiveBuffer.Count < WsHeaderSize)
                        {
                            for (int i = 0; i < 4; ++i, ++index, --size)
                            {
                                if (size == 0)
                                {
                                    return;
                                }
                                WsReceiveBuffer.Add(buffer[offset + index]);
                                WsReceiveMask[i] = buffer[offset + index];
                            }
                        }
                    }

                    int total  = WsHeaderSize + WsPayloadSize;
                    int length = Math.Min(total - WsReceiveBuffer.Count, (int)size);

                    // Prepare WebSocket frame payload
                    WsReceiveBuffer.AddRange(buffer.Skip(((int)offset + index)).Take(((int)length)));
                    index += length;
                    size  -= length;

                    // Process WebSocket frame
                    if (WsReceiveBuffer.Count == total)
                    {
                        int bufferOffset = WsHeaderSize;

                        // Unmask WebSocket frame content
                        if (mask)
                        {
                            for (int i = 0; i < WsPayloadSize; ++i)
                            {
                                WsReceiveBuffer[bufferOffset + i] ^= WsReceiveMask[i % 4];
                            }
                        }

                        WsReceived = true;

                        if ((opcode & WS_PING) == WS_PING)
                        {
                            // Call the WebSocket ping handler
                            _wsHandler.OnWsPing(WsReceiveBuffer.ToArray(), bufferOffset, WsPayloadSize);
                        }
                        else if ((opcode & WS_PONG) == WS_PONG)
                        {
                            // Call the WebSocket pong handler
                            _wsHandler.OnWsPong(WsReceiveBuffer.ToArray(), bufferOffset, WsPayloadSize);
                        }
                        else if ((opcode & WS_CLOSE) == WS_CLOSE)
                        {
                            // Call the WebSocket close handler
                            _wsHandler.OnWsClose(WsReceiveBuffer.ToArray(), bufferOffset, WsPayloadSize);
                        }
                        else if (((opcode & WS_TEXT) == WS_TEXT) || ((opcode & WS_BINARY) == WS_BINARY))
                        {
                            // Call the WebSocket received handler
                            _wsHandler.OnWsReceived(WsReceiveBuffer.ToArray(), bufferOffset, WsPayloadSize);
                        }
                    }
                }
            }
        }
Beispiel #3
0
        /// <summary>
        /// Prepare WebSocket send frame
        /// </summary>
        /// <param name="buffer">Buffer to send</param>
        /// <param name="offset">Buffer offset</param>
        /// <param name="size">Buffer size</param>
        public void PrepareReceiveFrame(byte[] buffer, long offset, long size)
        {
            lock (WsReceiveLock)
            {
                var index = 0;

                // Clear received data after WebSocket frame was processed
                if (WsReceived)
                {
                    WsReceived    = false;
                    WsHeaderSize  = 0;
                    WsPayloadSize = 0;
                    WsReceiveBuffer.Clear();
                    Array.Clear(WsReceiveMask, 0, WsReceiveMask.Length);
                }

                while (size > 0)
                {
                    // Clear received data after WebSocket frame was processed
                    if (WsReceived)
                    {
                        WsReceived    = false;
                        WsHeaderSize  = 0;
                        WsPayloadSize = 0;
                        WsReceiveBuffer.Clear();
                        Array.Clear(WsReceiveMask, 0, WsReceiveMask.Length);
                    }

                    // Prepare WebSocket frame opcode and mask flag
                    if (WsReceiveBuffer.Count < 2)
                    {
                        for (int i = 0; i < 2; ++i, ++index, --size)
                        {
                            if (size == 0)
                            {
                                return;
                            }
                            WsReceiveBuffer.Add(buffer[offset + index]);
                        }
                    }

                    byte opcode  = (byte)(WsReceiveBuffer[0] & 0x0F);
                    bool fin     = ((WsReceiveBuffer[0] >> 7) & 0x01) != 0;
                    bool mask    = ((WsReceiveBuffer[1] >> 7) & 0x01) != 0;
                    int  payload = WsReceiveBuffer[1] & (~0x80);

                    // Prepare WebSocket frame size
                    if (payload <= 125)
                    {
                        WsHeaderSize             = 2 + (mask ? 4 : 0);
                        WsPayloadSize            = payload;
                        WsReceiveBuffer.Capacity = WsHeaderSize + WsPayloadSize;
                    }
                    else if (payload == 126)
                    {
                        if (WsReceiveBuffer.Count < 4)
                        {
                            for (int i = 0; i < 2; ++i, ++index, --size)
                            {
                                if (size == 0)
                                {
                                    return;
                                }
                                WsReceiveBuffer.Add(buffer[offset + index]);
                            }
                        }

                        payload                  = ((WsReceiveBuffer[2] << 8) | (WsReceiveBuffer[3] << 0));
                        WsHeaderSize             = 4 + (mask ? 4 : 0);
                        WsPayloadSize            = payload;
                        WsReceiveBuffer.Capacity = WsHeaderSize + WsPayloadSize;
                    }
                    else if (payload == 127)
                    {
                        if (WsReceiveBuffer.Count < 10)
                        {
                            for (int i = 0; i < 8; ++i, ++index, --size)
                            {
                                if (size == 0)
                                {
                                    return;
                                }
                                WsReceiveBuffer.Add(buffer[offset + index]);
                            }
                        }

                        payload                  = ((WsReceiveBuffer[2] << 56) | (WsReceiveBuffer[3] << 48) | (WsReceiveBuffer[4] << 40) | (WsReceiveBuffer[5] << 32) | (WsReceiveBuffer[6] << 24) | (WsReceiveBuffer[7] << 16) | (WsReceiveBuffer[8] << 8) | (WsReceiveBuffer[9] << 0));
                        WsHeaderSize             = 10 + (mask ? 4 : 0);
                        WsPayloadSize            = payload;
                        WsReceiveBuffer.Capacity = WsHeaderSize + WsPayloadSize;
                    }

                    // Prepare WebSocket frame mask
                    if (mask)
                    {
                        if (WsReceiveBuffer.Count < WsHeaderSize)
                        {
                            for (int i = 0; i < 4; ++i, ++index, --size)
                            {
                                if (size == 0)
                                {
                                    return;
                                }
                                WsReceiveBuffer.Add(buffer[offset + index]);
                                WsReceiveMask[i] = buffer[offset + index];
                            }
                        }
                    }

                    int total  = WsHeaderSize + WsPayloadSize;
                    int length = Math.Min(total - WsReceiveBuffer.Count, (int)size);

                    // Prepare WebSocket frame payload
                    WsReceiveBuffer.AddRange(buffer[((int)offset + index)..((int)offset + index + length)]);