예제 #1
0
        public void SendWebSocketText(string text)
        {
            var data = Encoding.GetEncoding(1252).GetBytes(text);

            var buffer = new DataBuffer();

            buffer.Write((byte)0x81); // text frame and FIN

            if (data.Length <= 125)
            {
                buffer.Write((byte)data.Length);
            }
            else if (data.Length <= ushort.MaxValue)
            {
                // needs the masking shit??
                buffer.Write((byte)126);
                buffer.Write((short)WebSocketHeader.ReverseBytes((ushort)data.Length));
            }
            else
            {
                buffer.Write((byte)127);
                buffer.Write((long)WebSocketHeader.ReverseBytes((ulong)data.Length));
            }

            buffer.Write(data, 0, data.Length);

            Send(buffer);
        }
예제 #2
0
        public const long MaxPayloadSize         = 8388608; // 8 MB

        private void ProcessWebSocketData(WebSocketClient client, byte[] buffer, int offset, int length)
        {
            if (client.Buffer.Length + length > MaxWebSocketDataLength)
            {
                client.Disconnect("WebSocket buffer overflow");
                return;
            }

            client.Buffer.Offset = client.Buffer.Length;
            client.Buffer.Write(buffer, offset, length);

            var header = new WebSocketHeader();

            while (client.Buffer.Length > 0)
            {
                client.Buffer.Offset = 0;

                var result = header.Read(client.Buffer);
                if (result != WebSocketHeaderReadResult.Succeeded)
                {
                    if (result != WebSocketHeaderReadResult.NeedMoreData)
                    {
                        client.Disconnect("WebSocket protocol error");
                    }

                    break;
                }

                /*if (header.OpCode != WebSocketOpCode.Text &&
                 *  header.OpCode )
                 * {
                 *  Logger.Log(LogType.Warning, "Unsupported WebSocket OpCode: {0}", header.OpCode);
                 *  webClient.Disconnect();
                 *  break;
                 * }*/

                if (header.PayloadSize > MaxPayloadSize)
                {
                    client.Disconnect("Too big websocket packet received. Payload size: " + header.PayloadSize);
                    break;
                }

                if (!header.Masked)
                {
                    client.Disconnect("WebSocket clients must send masked data.");
                    break;
                }

                if (!header.Finished)
                {
                    client.Disconnect("Continuation frames not supported.");
                    break;
                }

                // parse
                if (client.Buffer.Offset + header.PayloadSize <= client.Buffer.Length) // check if we received all data
                {
                    if (header.Masked)
                    {
                        DecodeWebSocketData(
                            header.Mask,
                            client.Buffer.InternalBuffer,
                            client.Buffer.Offset,
                            (int)header.PayloadSize);
                    }

                    if (header.PayloadSize > 0 &&
                        header.OpCode == WebSocketOpCode.Text)
                    {
                        var str_data = Encoding.GetEncoding(1252).GetString(
                            client.Buffer.InternalBuffer,
                            client.Buffer.Offset,
                            (int)header.PayloadSize);

                        OnWebSocketData(
                            client,
                            str_data);
                    }

                    if (client.IsDisconnect)
                    {
                        break;
                    }

                    // delete from buffer
                    client.Buffer.Remove(header.HeaderSize + (int)header.PayloadSize);
                }
                else
                {
                    return; // need more data
                }
            }
        }