Beispiel #1
0
        private void ProcessFrame(FrameType frameType, ArraySegment <byte> data)
        {
            switch (frameType)
            {
            case FrameType.Close:
                if (data.Count == 1 || data.Count > 125)
                {
                    throw new WebSocketException(WebSocketStatusCodes.ProtocolError);
                }

                if (data.Count >= 2)
                {
                    var closeCode = (ushort)new Span <byte>(data.Array, 0, 2).ToLittleEndianInt();
                    if (!WebSocketStatusCodes.ValidCloseCodes.Contains(closeCode) && (closeCode < 3000 || closeCode > 4999))
                    {
                        throw new WebSocketException(WebSocketStatusCodes.ProtocolError);
                    }
                }

                _connection.OnClose?.Invoke();
                break;

            case FrameType.Binary:
                _connection.OnBinary?.Invoke(data);
                break;

            case FrameType.Ping:
                _connection.OnPing?.Invoke(data);
                break;

            case FrameType.Pong:
                _connection.OnPong?.Invoke(data);
                break;

            case FrameType.Text:
                _connection.OnMessage?.Invoke(ReadUTF8PayloadData(data));
                break;

            default:
                FleckLog.Debug("Received unhandled " + frameType);
                break;
            }
        }
Beispiel #2
0
 private void ListenForClients()
 {
     ListenerSocket.Accept(OnClientConnect, e => {
         FleckLog.Error("Listener socket is closed", e);
         if (RestartAfterListenError)
         {
             FleckLog.Info("Listener socket restarting");
             try {
                 ListenerSocket.Dispose();
                 Socket socket = new Socket(_locationIP.AddressFamily, SocketType.Stream, ProtocolType.IP);
                 socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, 1);
                 ListenerSocket = new SocketWrapper(socket);
                 Start(_config);
                 FleckLog.Info("Listener socket restarted");
             } catch (Exception ex) {
                 FleckLog.Error("Listener could not be restarted", ex);
             }
         }
     });
 }
Beispiel #3
0
        public static byte[] BuildHandshake(WebSocketHttpRequest request, string subProtocol)
        {
            FleckLog.Debug("Building Hybi-14 Response");

            var builder = new StringBuilder();

            builder.Append("HTTP/1.1 101 Switching Protocols\r\n");
            builder.Append("Upgrade: websocket\r\n");
            builder.Append("Connection: Upgrade\r\n");
            if (subProtocol != null)
            {
                builder.AppendFormat("Sec-WebSocket-Protocol: {0}\r\n", subProtocol);
            }

            var responseKey = CreateResponseKey(request["Sec-WebSocket-Key"]);

            builder.AppendFormat("Sec-WebSocket-Accept: {0}\r\n", responseKey);
            builder.Append("\r\n");

            return(Encoding.ASCII.GetBytes(builder.ToString()));
        }
Beispiel #4
0
        public MemoryBuffer CreateHandshake()
        {
            FleckLog.Debug("Building Hybi-14 Response");

            var builder = StringBuilder.Value;

            builder.Clear();

            builder.Append("HTTP/1.1 101 Switching Protocols\r\n");
            builder.Append("Upgrade: websocket\r\n");
            builder.Append("Connection: Upgrade\r\n");

            var responseKey = CreateResponseKey(_request["Sec-WebSocket-Key"]);

            builder.AppendFormat("Sec-WebSocket-Accept: {0}\r\n", responseKey);
            builder.Append("\r\n");

            var bytes = UTF8.GetBytes(builder.ToString());

            return(new MemoryBuffer(bytes, bytes.Length, false));
        }
Beispiel #5
0
        public static void ProcessFrame(FrameType frameType, byte[] data, Action <string> onMessage, Fleck2Extensions.Action onClose, Action <byte[]> onBinary)
        {
            switch (frameType)
            {
            case FrameType.Close:
                if (data.Length == 1 || data.Length > 125)
                {
                    throw new WebSocketException(WebSocketStatusCodes.ProtocolError);
                }

                if (data.Length >= 2)
                {
                    var closeCode = (ushort)(data.Take(2).ToArray().ToLittleEndianInt());
                    if (!WebSocketStatusCodes.Contains(closeCode) && (closeCode < 3000 || closeCode > 4999))
                    {
                        throw new WebSocketException(WebSocketStatusCodes.ProtocolError);
                    }
                }

                if (data.Length > 2)
                {
                    ReadUtf8PayloadData(data.Skip(2));
                }

                onClose();
                break;

            case FrameType.Binary:
                onBinary(data);
                break;

            case FrameType.Text:
                onMessage(ReadUtf8PayloadData(data));
                break;

            default:
                FleckLog.Debug("Received unhandled " + frameType);
                break;
            }
        }
Beispiel #6
0
        static void Log(string message, LogLevel level, Exception ex = null)
        {
            switch (level)
            {
            case LogLevel.Debug:
                FleckLog.Debug(message, ex);
                break;

            case LogLevel.Info:
                FleckLog.Info(message, ex);
                break;

            case LogLevel.Warn:
                FleckLog.Warn(message, ex);
                break;

            case LogLevel.Error:
                FleckLog.Error(message, ex);
                break;
            }

            Console.ResetColor();
        }
Beispiel #7
0
        public static byte[] Handshake(WebSocketHttpRequest request, string subProtocol)
        {
            FleckLog.Debug("Building Draft76 Response");

            var builder = new StringBuilder();

            builder.Append("HTTP/1.1 101 WebSocket Protocol Handshake\r\n");
            builder.Append("Upgrade: WebSocket\r\n");
            builder.Append("Connection: Upgrade\r\n");
            builder.AppendFormat("Sec-WebSocket-Origin: {0}\r\n", request["Origin"]);
            builder.AppendFormat("Sec-WebSocket-Location: {0}://{1}{2}\r\n", request.Scheme, request["Host"], request.Path);

            if (subProtocol != null)
            {
                builder.AppendFormat("Sec-WebSocket-Protocol: {0}\r\n", subProtocol);
            }

            builder.Append("\r\n");

            var key1      = request["Sec-WebSocket-Key1"];
            var key2      = request["Sec-WebSocket-Key2"];
            var challenge = new ArraySegment <byte>(request.Bytes, request.Bytes.Length - 8, 8);

            var answerBytes = CalculateAnswerBytes(key1, key2, challenge);

#if !PORTABLE
            byte[] byteResponse = Encoding.ASCII.GetBytes(builder.ToString());
#else
            byte[] byteResponse = Encoding.GetEncoding("ISO-8859-1").GetBytes(builder.ToString());
#endif
            int byteResponseLength = byteResponse.Length;
            Array.Resize(ref byteResponse, byteResponseLength + answerBytes.Length);
            Array.Copy(answerBytes, 0, byteResponse, byteResponseLength, answerBytes.Length);

            return(byteResponse);
        }
Beispiel #8
0
 public static byte[] Handshake(WebSocketHttpRequest request, string subProtocol)
 {
     FleckLog.Trace("Building Flash Socket Policy Response");
     return(Encoding.UTF8.GetBytes(PolicyResponse));
 }
Beispiel #9
0
        private void ReceiveData()
        {
            while (_dataLen >= 2)
            {
                FleckLog.Debug("Trying to read a packet");

                var isFinal      = (_data[0] & 128) != 0;
                var reservedBits = (_data[0] & 112);
                var frameType    = (FrameType)(_data[0] & 15);
                var isMasked     = (_data[1] & 128) != 0;
                var length       = (_data[1] & 127);


                if (!isMasked ||
                    !frameType.IsDefined() ||
                    reservedBits != 0 || // Must be zero per spec 5.2
                    (frameType == FrameType.Continuation && !_frameType.HasValue))
                {
                    throw new WebSocketException(WebSocketStatusCodes.ProtocolError);
                }

                var index = 2;
                int payloadLength;

                if (length == 127)
                {
                    if (_dataLen < index + 8)
                    {
                        return; //Not complete
                    }
                    payloadLength = new Span <byte>(_data, index, 8).ToLittleEndianInt();
                    index        += 8;
                }
                else if (length == 126)
                {
                    if (_dataLen < index + 2)
                    {
                        return; //Not complete
                    }
                    payloadLength = new Span <byte>(_data, index, 2).ToLittleEndianInt();
                    index        += 2;
                }
                else
                {
                    payloadLength = length;
                }

                FleckLog.Debug($"Expecting {payloadLength} byte payload");

                if (_dataLen < index + 4)
                {
                    return; //Not complete
                }
                var maskBytes = new Span <byte>(_data, index, 4);
                index += 4;

                if (_dataLen < index + payloadLength)
                {
                    return; //Not complete
                }
                var payloadData = new Span <byte>(_data, index, payloadLength);
                for (var i = 0; i < payloadLength; i++)
                {
                    payloadData[i] = (byte)(payloadData[i] ^ maskBytes[i % 4]);
                }

                if (_messageLen + payloadLength > _message.Length)
                {
                    throw new WebSocketException(WebSocketStatusCodes.MessageTooBig);
                }

                var messageDest = new Span <byte>(_message, _messageLen, payloadLength);
                payloadData.CopyTo(messageDest);
                _messageLen += payloadLength;

                var bytesUsed = index + payloadLength;
                Buffer.BlockCopy(_data, bytesUsed, _data, 0, _dataLen - bytesUsed);
                _dataLen -= index + payloadLength;

                if (frameType != FrameType.Continuation)
                {
                    _frameType = frameType;
                }

                if (isFinal && _frameType.HasValue)
                {
                    FleckLog.Debug($"Frame finished: {_frameType.Value}, {_messageLen} bytes");

                    ProcessFrame(_frameType.Value, new ArraySegment <byte>(_message, 0, _messageLen));
                    Clear();
                }
            }
        }
 public static byte[] Handshake(WebSocketHttpRequest request, string subProtocol)
 {
     FleckLog.Debug("Building Flash Socket Policy Response");
     Log.Insert(DateTime.Now, "FlashSocketPolicyRequestHandler.cs", string.Format("Building Flash Socket Policy Response"), "white");
     return(Encoding.UTF8.GetBytes(PolicyResponse));
 }
Beispiel #11
0
        /// <summary>
        /// 启动连接状态检查线程
        /// 执行rtmp的读写异步任务
        /// </summary>
        void ClientWorkHandler()
        {
            _clientWorkThread = new Thread(() =>
            {
                while (true)
                {
                    try
                    {
                        if (ClientSessions.Count() < 1)
                        {
                            Thread.Sleep(1);
                            continue;
                        }

                        ClientSessionDictionary nclientSessions = null;

                        lock (_locker)
                        {
                            nclientSessions = ClientSessions.Clone() as ClientSessionDictionary;
                        }

                        Parallel.ForEach(nclientSessions, current =>
                        {
                            ClientSession state    = current.Value;
                            ushort client_id       = current.Key;
                            IStreamConnect connect = state.Connect;

                            try
                            {
                                if (connect.IsDisconnected)
                                {
                                    DisconnectSession(client_id);
                                }
                                else
                                {
                                    if (state.WriterTask == null)
                                    {
                                        state.WriterTask = connect.WriteOnceAsync();
                                    }
                                    else
                                    {
                                        if (state.WriterTask.IsCompleted)
                                        {
                                            state.WriterTask = connect.WriteOnceAsync();
                                        }
                                        if (state.WriterTask.IsCanceled || state.WriterTask.IsFaulted)
                                        {
                                            this.DisconnectSession(current.Key);
                                            //throw state.WriterTask.Exception;
                                        }
                                        if (state.LastPing == null || DateTime.UtcNow - state.LastPing >= new TimeSpan(0, 0, _pingPeriod))
                                        {
                                            connect.PingAsync(_pingTimeout);
                                            state.LastPing = DateTime.UtcNow;
                                        }

                                        if (state.ReaderTask == null || state.ReaderTask.IsCompleted)
                                        {
                                            state.ReaderTask = connect.ReadOnceAsync();
                                        }

                                        if (state.ReaderTask.IsCanceled || state.ReaderTask.IsFaulted)
                                        {
                                            this.DisconnectSession(current.Key);
                                            //throw state.ReaderTask.Exception;
                                        }
                                    }
                                }
                            }
                            catch
                            {
                                DisconnectSession(client_id);
                            }
                        });
                    }
                    catch (Exception ex)
                    {
                        FleckLog.Error("ConnectStateCheckUp.Thread.Error", ex);
                    }
                }
            })
            {
                IsBackground = true
            };
            _clientWorkThread.Start();
        }