private void Listen() { // Listen State Task.Factory.StartNew(async() => { while (true) { await Task.Delay(500); if (_socket.State == WebSocketState.Aborted || _socket.State == WebSocketState.Closed) { if (State != SocketIOState.Closed) { State = SocketIOState.Closed; _tokenSource.Cancel(); OnClosed?.Invoke(ServerCloseReason.Aborted); } } } }, _tokenSource.Token); // Listen Message Task.Factory.StartNew(async() => { var buffer = new byte[ReceiveChunkSize]; while (true) { if (_socket.State == WebSocketState.Open) { WebSocketReceiveResult result = await _socket.ReceiveAsync(new ArraySegment <byte>(buffer), _tokenSource.Token); if (result.MessageType == WebSocketMessageType.Text) { var builder = new StringBuilder(); string str = Encoding.UTF8.GetString(buffer, 0, result.Count); builder.Append(str); while (!result.EndOfMessage) { result = await _socket.ReceiveAsync(new ArraySegment <byte>(buffer), _tokenSource.Token); str = Encoding.UTF8.GetString(buffer, 0, result.Count); builder.Append(str); } var parser = new ResponseTextParser(_namespace, this) { Text = builder.ToString() }; await parser.ParseAsync(); } } } }, _tokenSource.Token); }
private async void ReceiverLoop(object obj) { WebSocketReceiveResult r; var buffer = new byte[ReceiveChunkSize]; var bufferSegment = new ArraySegment <byte>(buffer); pingRequestDeadline = Environment.TickCount + (int)PingInterval.TotalMilliseconds; pongTimeoutDeadline = Environment.TickCount + (int)PingTimeout.TotalMilliseconds; Task <WebSocketReceiveResult> tReceive = null; Task tPing = null; while (_socket.State == WebSocketState.Open) { try { if (tReceive == null) { tReceive = _socket.ReceiveAsync(bufferSegment, CancellationToken.None); } } catch (ObjectDisposedException) { break; } if (tPing == null) { tPing = Task.Delay(Math.Max(0, Math.Min(pingRequestDeadline - Environment.TickCount, pongTimeoutDeadline - Environment.TickCount))); } var t = await Task.WhenAny(tReceive, tPing); if (t == tReceive) { try { r = await tReceive; tReceive = null; } catch (WebSocketException) { // Disconnection? break; } switch (r.MessageType) { case WebSocketMessageType.Text: if (r.Count > 0) { // Defalut engine.io protocol switch (buffer[0]) { case (byte)'3': // Server Pong pongTimeoutDeadline = Environment.TickCount + (int)PingTimeout.TotalMilliseconds; PingEventArgs pingArgs = new PingEventArgs(pingRequestAt, Environment.TickCount); OnPing?.Invoke(pingArgs); break; case (byte)'4': // Message if (r.Count > 1) { // Defalut socket.io protocol switch (buffer[1]) { // Ignore All of them. it's just for understanding ! case (byte)'0': // Connect case (byte)'1': // Disconnect // Ignored break; case (byte)'2': // Event case (byte)'3': // Ack case (byte)'4': // Error case (byte)'5': // Binary_Event case (byte)'6': // Binary_Ack // Ignored break; } } // Listen to message var builder = new StringBuilder(); string str = Encoding.UTF8.GetString(buffer, 0, r.Count); builder.Append(str); while (!r.EndOfMessage) { r = await _socket.ReceiveAsync(new ArraySegment <byte>(buffer), _tokenSource.Token); str = Encoding.UTF8.GetString(buffer, 0, r.Count); builder.Append(str); } var parser = new ResponseTextParser(_namespace, this) { Text = builder.ToString() }; await parser.ParseAsync(); break; } } break; case WebSocketMessageType.Binary: case WebSocketMessageType.Close: default: // Nothing to handle break; } } else { if (Environment.TickCount - pingRequestDeadline >= 0) { if (Interlocked.CompareExchange(ref pingRequest, 1, 0) == 0) { pingRequest = 1; WakeSenderLoop(); pingRequestDeadline = Environment.TickCount + (int)PingInterval.TotalMilliseconds; pongTimeoutDeadline = Environment.TickCount + (int)PingTimeout.TotalMilliseconds; } } if (Environment.TickCount - pongTimeoutDeadline >= 0) { // Ping timeout try { await _socket.CloseAsync(WebSocketCloseStatus.EndpointUnavailable, "Ping timeout", CancellationToken.None); } catch (WebSocketException) { } catch (ObjectDisposedException) { } break; } } } serverCloseReason = ServerCloseReason.SocketAborted; await CloseAsync(); }
private void Listen() { // Listen State Task.Factory.StartNew(async() => { while (true) { await Task.Delay(500); if (!_isHeartbeatFinished) { _heartbeatDelay += 500; } if (!_isConnectTimeout && _heartbeatDelay >= _heartbeatTimeoutDelay) { _isConnectTimeout = true; if (_timeoutNumber == 0) { InvokeConnectTimeout(); } _timeoutNumber++; if (_timeoutNumber == 2) { await CloseAsync(); } } if (_socket.State == WebSocketState.Aborted || _socket.State == WebSocketState.Closed) { if (State != SocketIOState.Closed) { State = SocketIOState.Closed; _tokenSource.Cancel(); OnClosed?.Invoke(ServerCloseReason.Aborted); } } } }, _tokenSource.Token); // Listen Message Task.Factory.StartNew(async() => { while (true) { var buffer = new byte[ReceiveChunkSize]; Console.WriteLine("_socket.State " + _socket.State.ToString()); if (_socket.State == WebSocketState.Open) { WebSocketReceiveResult result = await _socket.ReceiveAsync(new ArraySegment <byte> (buffer), _tokenSource.Token); if (result.MessageType == WebSocketMessageType.Text) { var bufferList = new List <byte> (); byte[] bufferTotal; int totalCount = 0; bufferList.AddRange(buffer); totalCount += result.Count; while (!result.EndOfMessage) { result = await _socket.ReceiveAsync(new ArraySegment <byte> (buffer), _tokenSource.Token); totalCount += result.Count; bufferList.AddRange(buffer); } bufferTotal = bufferList.ToArray(); Console.WriteLine($"GetWebSocket Data in len: {bufferList.Count()}, data: {Encoding.UTF8.GetString(bufferTotal, 0, totalCount)}"); var parser = new ResponseTextParser(_namespace, this) { Text = Encoding.UTF8.GetString(bufferTotal, 0, totalCount) }; //Console.WriteLine("parser.ParseAsync" + parser.Text); await parser.ParseAsync(); } else if (result.MessageType == WebSocketMessageType.Binary) { string str = "binary"; try { str = Encoding.UTF8.GetString(buffer, 0, result.Count); } catch (Exception e) { Console.WriteLine(e.ToString()); } Console.WriteLine("GetWebSocket Data : " + str); } } else { Thread.Sleep(1000); } } }, _tokenSource.Token); }