From f215f3c53f6920194faae6be8bddc04e35f1588c Mon Sep 17 00:00:00 2001 From: JKorf Date: Tue, 4 Dec 2018 15:33:13 +0100 Subject: [PATCH] Added no data timeout in socket --- CryptoExchange.Net/Interfaces/IWebsocket.cs | 1 + CryptoExchange.Net/Sockets/BaseSocket.cs | 30 ++++++++++++++++++++- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/CryptoExchange.Net/Interfaces/IWebsocket.cs b/CryptoExchange.Net/Interfaces/IWebsocket.cs index 44119e3..f0f081b 100644 --- a/CryptoExchange.Net/Interfaces/IWebsocket.cs +++ b/CryptoExchange.Net/Interfaces/IWebsocket.cs @@ -23,6 +23,7 @@ namespace CryptoExchange.Net.Interfaces bool PingConnection { get; set; } TimeSpan PingInterval { get; set; } SslProtocols SSLProtocols { get; set; } + TimeSpan Timeout { get; set; } Task Connect(); void Send(string data); Task Close(); diff --git a/CryptoExchange.Net/Sockets/BaseSocket.cs b/CryptoExchange.Net/Sockets/BaseSocket.cs index 948fa49..fbb809c 100644 --- a/CryptoExchange.Net/Sockets/BaseSocket.cs +++ b/CryptoExchange.Net/Sockets/BaseSocket.cs @@ -39,6 +39,10 @@ namespace CryptoExchange.Net.Sockets public SslProtocols SSLProtocols { get; set; } = SslProtocols.Tls12 | SslProtocols.Tls11 | SslProtocols.Tls; public Func DataInterpreter { get; set; } + public DateTime LastActionTime { get; private set; } + public TimeSpan Timeout { get; set; } + private Task timeoutTask; + public bool PingConnection { get => socket.EnableAutoSendPing; @@ -101,18 +105,38 @@ namespace CryptoExchange.Net.Sockets remove => openHandlers.Remove(value); } - protected static void Handle(List handlers) + protected void Handle(List handlers) { + LastActionTime = DateTime.UtcNow; foreach (var handle in new List(handlers)) handle?.Invoke(); } protected void Handle(List> handlers, T data) { + LastActionTime = DateTime.UtcNow; foreach (var handle in new List>(handlers)) handle?.Invoke(data); } + protected void CheckTimeout() + { + while (true) + { + if (socket == null || socket.State != WebSocketState.Open) + return; + + if (DateTime.UtcNow - LastActionTime > Timeout) + { + log.Write(LogVerbosity.Warning, $"No data received for {Timeout}, reconnecting socket"); + Close().Wait(); + return; + } + + Thread.Sleep(500); + } + } + public virtual async Task Close() { await Task.Run(() => @@ -202,7 +226,11 @@ namespace CryptoExchange.Net.Sockets } connected = socket.State == WebSocketState.Open; if (connected) + { log?.Write(LogVerbosity.Debug, $"Socket {Id} connected"); + if ((timeoutTask == null || timeoutTask.IsCompleted) && Timeout != default(TimeSpan)) + timeoutTask = Task.Run(() => CheckTimeout()); + } else log?.Write(LogVerbosity.Debug, $"Socket {Id} connection failed, state: " + socket.State); }