private async Task KeepAlive() { var count = AsyncTcp.KeepAliveInterval; await Task.Delay(delayMS).ConfigureAwait(false); while (_alive) { if (count == AsyncTcp.KeepAliveInterval) { count = 0; Interlocked.Increment(ref _keepAliveCount); // If we have counted at least 3 keepAlives and we havn't received any assume the connection is closed if (_alive && _keepAliveCount >= 3) { AsyncTcp.Log(PeerId, "KeepAlive Count >= 3, Shutting Down"); ShutDown(); break; } await Send(AsyncTcp.KeepAliveType).ConfigureAwait(false); } else { count++; } await Task.Delay(delayMS).ConfigureAwait(false); } }
public async Task Send(int type, ReadOnlyMemory <byte> buffer) { try { await _sendLock.WaitAsync().ConfigureAwait(false); int bytesSent; if (buffer.Length == 0) { bytesSent = 0; while (bytesSent < 8) { bytesSent += await _socket .SendAsync(new ArraySegment <byte>(AsyncTcp.Headers(type), bytesSent, 8 - bytesSent), SocketFlags.None) .ConfigureAwait(false); } // If the packet type is of ErrorType call Shutdown and let the peer gracefully finish processing if (type == AsyncTcp.ErrorType) { ShutDown(); } return; } var header = AsyncTcp.GetHeaderBuffer(); WriteHeader(header, type, buffer.Length); bytesSent = 0; while (bytesSent < 8) { bytesSent += await _socket .SendAsync(new ArraySegment <byte>(header, bytesSent, 8 - bytesSent), SocketFlags.None) .ConfigureAwait(false); } var segment = buffer.GetArray(); bytesSent = 0; while (bytesSent < segment.Count) { bytesSent += await _socket .SendAsync(new ArraySegment <byte>(segment.Array, segment.Offset + bytesSent, segment.Count - bytesSent), SocketFlags.None) .ConfigureAwait(false); } } catch { } finally { _sendLock.Release(); } }
private async Task ProcessReceive() { var info = new ParseInfo(); // 1 Alloc for reference values var reader = PipeReader.Create(new NetworkStream(_socket), AsyncTcp.ReceivePipeOptions); try { while (true) { var result = await reader.ReadAsync().ConfigureAwait(false); var buffer = result.Buffer; // Handle Keep Alive Check if (info.Type == AsyncTcp.KeepAliveType) { // Reset our KeepAliveCount to indicate we have received some data from the client Interlocked.Exchange(ref _keepAliveCount, 0); } // Parse as many messages as we can from the buffer while (TryParseBuffer(ref buffer, info)) { await AsyncTcp.PeerHandler.Receive(this, info.Type, info.Buffer).ConfigureAwait(false); } reader.AdvanceTo(buffer.Start, buffer.End); if (result.IsCompleted) { break; } } } catch { ShutDown(); } await reader.CompleteAsync().ConfigureAwait(false); AsyncTcp.Log(PeerId, "COMPLETED RECEIVE"); }
public async Task SendUnreliable(int type, object payload) { if (payload == null) { try { await _udpSocket .SendToAsync(new ArraySegment <byte>(AsyncTcp.HeaderBytes(type)), SocketFlags.None, _peer.EndPoint) .ConfigureAwait(false); } catch { } return; } using (var stream = AsyncTcp.StreamManager.GetStream()) { // Skip the header and pack the stream stream.Position = 8; await AsyncTcp.PeerHandler.PackUnreliableMessage(_peer, type, payload, stream).ConfigureAwait(false); // Go back and write the header now that we know the size stream.Position = 0; WriteHeader(stream, type, (int)stream.Length - 8); stream.Position = 0; if (stream.TryGetBuffer(out var buffer)) { try { await _udpSocket .SendToAsync(new ArraySegment <byte>(buffer.Array, buffer.Offset, buffer.Count), SocketFlags.None, _peer.EndPoint) .ConfigureAwait(false); } catch { } } } await AsyncTcp.PeerHandler.DisposeMessage(_peer, type, payload).ConfigureAwait(false); }