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; } }
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); } } }); }
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())); }
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)); }
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; } }
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(); }
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); }
public static byte[] Handshake(WebSocketHttpRequest request, string subProtocol) { FleckLog.Trace("Building Flash Socket Policy Response"); return(Encoding.UTF8.GetBytes(PolicyResponse)); }
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)); }
/// <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(); }