protected internal virtual void PollEventsInternal() { if (Parent.Configuration.KeepAliveEnabled) { TimeSpan timeSinceLastKeepAlive = DateTime.UtcNow - this.lastKeepAliveSent; if (keepAliveResponseGot) { if (timeSinceLastKeepAlive.TotalMilliseconds > Parent.Configuration.KeepAliveInterval) { keepAliveResponseGot = false; this.lastKeepAliveSent = DateTime.UtcNow; _ = SendMessageAsync(TcpRawMessage.GetEmpty(Parent.Configuration.MemoryStreamPool, MessageHeaderFlags.KeepAliveRequest)); } } else { if (timeSinceLastKeepAlive.TotalMilliseconds > TcpConnectionStatistics.UNSTABLE_CONNECTION_TIMEOUT) { Statistics.SetUnstable(); } if (Parent.Configuration.KeepAliveTimeout > Timeout.Infinite && timeSinceLastKeepAlive.TotalMilliseconds > Parent.Configuration.KeepAliveTimeout) { logger.Debug($"Connection #{Id} closing, KeepAliveTimeout exceeded"); Close(); } } } Statistics.PollEvents(); while (latencySimulationRecvQueue.Count > 0 && Connected) { if (latencySimulationRecvQueue.TryPeek(out DelayedMessage msg)) { if (DateTime.UtcNow > msg.releaseTimestamp) { latencySimulationRecvQueue.TryDequeue(out DelayedMessage _msg); OnMessageReceivedInternal(msg.message); } else { break; } } else { break; } } }
void OnMessageReceivedInternal(TcpRawMessage message) { if (message.Flags.HasFlag(MessageHeaderFlags.KeepAliveRequest) || message.Flags.HasFlag(MessageHeaderFlags.KeepAliveResponse)) { logger.Trace($"Connection #{Id} recv message {message}"); } else { logger.Debug($"Connection #{Id} recv message {message}"); } if (message.Flags.HasFlag(MessageHeaderFlags.KeepAliveRequest)) { LastKeepAliveRequestReceived = DateTime.UtcNow; _ = SendMessageAsync(TcpRawMessage.GetEmpty(Parent.Configuration.MemoryStreamPool, MessageHeaderFlags.KeepAliveResponse)); message.Dispose(); return; } if (message.Flags.HasFlag(MessageHeaderFlags.KeepAliveResponse)) { Statistics.UpdateLatency((float)(DateTime.UtcNow - this.lastKeepAliveSent).TotalMilliseconds); keepAliveResponseGot = true; message.Dispose(); return; } Parent.Configuration.SynchronizeSafe(() => { try { OnMessageReceived(new MessageEventArgs(this, message)); } catch (Exception ex) { logger.Error($"Unhandled exception in #{Id} -> {this.GetType().Name}.OnMessageReceived: {ex}"); } }, logger); }