mirror of
https://github.com/JKorf/CryptoExchange.Net
synced 2025-06-08 16:36:15 +00:00
Merge branch 'master' of https://github.com/JKorf/CryptoExchange.Net
This commit is contained in:
commit
2b1c77577c
@ -32,6 +32,7 @@ namespace CryptoExchange.Net.UnitTests.TestImplementations
|
|||||||
public SslProtocols SSLProtocols { get; set; }
|
public SslProtocols SSLProtocols { get; set; }
|
||||||
|
|
||||||
public int ConnectCalls { get; private set; }
|
public int ConnectCalls { get; private set; }
|
||||||
|
public bool Reconnecting { get; set; }
|
||||||
|
|
||||||
public static int lastId = 0;
|
public static int lastId = 0;
|
||||||
public static object lastIdLock = new object();
|
public static object lastIdLock = new object();
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<PackageId>CryptoExchange.Net</PackageId>
|
<PackageId>CryptoExchange.Net</PackageId>
|
||||||
<Authors>JKorf</Authors>
|
<Authors>JKorf</Authors>
|
||||||
<PackageVersion>2.0.3</PackageVersion>
|
<PackageVersion>2.0.6</PackageVersion>
|
||||||
<PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
|
<PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
|
||||||
<PackageProjectUrl>https://github.com/JKorf/CryptoExchange.Net</PackageProjectUrl>
|
<PackageProjectUrl>https://github.com/JKorf/CryptoExchange.Net</PackageProjectUrl>
|
||||||
<PackageLicenseUrl>https://github.com/JKorf/CryptoExchange.Net/blob/master/LICENSE</PackageLicenseUrl>
|
<PackageLicenseUrl>https://github.com/JKorf/CryptoExchange.Net/blob/master/LICENSE</PackageLicenseUrl>
|
||||||
|
@ -14,6 +14,7 @@ namespace CryptoExchange.Net.Interfaces
|
|||||||
|
|
||||||
int Id { get; }
|
int Id { get; }
|
||||||
bool ShouldReconnect { get; set; }
|
bool ShouldReconnect { get; set; }
|
||||||
|
bool Reconnecting { get; set; }
|
||||||
Func<byte[], string> DataInterpreter { get; set; }
|
Func<byte[], string> DataInterpreter { get; set; }
|
||||||
DateTime? DisconnectTime { get; set; }
|
DateTime? DisconnectTime { get; set; }
|
||||||
string Url { get; }
|
string Url { get; }
|
||||||
|
@ -169,6 +169,11 @@ namespace CryptoExchange.Net
|
|||||||
{
|
{
|
||||||
if (socket.ShouldReconnect)
|
if (socket.ShouldReconnect)
|
||||||
{
|
{
|
||||||
|
if (socket.Reconnecting)
|
||||||
|
return; // Already reconnecting
|
||||||
|
|
||||||
|
socket.Reconnecting = true;
|
||||||
|
|
||||||
log.Write(LogVerbosity.Info, $"Socket {socket.Id} Connection lost, will try to reconnect");
|
log.Write(LogVerbosity.Info, $"Socket {socket.Id} Connection lost, will try to reconnect");
|
||||||
Task.Run(() =>
|
Task.Run(() =>
|
||||||
{
|
{
|
||||||
@ -191,6 +196,7 @@ namespace CryptoExchange.Net
|
|||||||
lock (sockets)
|
lock (sockets)
|
||||||
subscription = sockets.Single(s => s.Socket == socket);
|
subscription = sockets.Single(s => s.Socket == socket);
|
||||||
|
|
||||||
|
socket.Reconnecting = false;
|
||||||
if (!SocketReconnect(subscription, DateTime.UtcNow - time.Value))
|
if (!SocketReconnect(subscription, DateTime.UtcNow - time.Value))
|
||||||
socket.Close().Wait(); // Close so we end up reconnecting again
|
socket.Close().Wait(); // Close so we end up reconnecting again
|
||||||
else
|
else
|
||||||
|
@ -32,7 +32,10 @@ namespace CryptoExchange.Net.Sockets
|
|||||||
|
|
||||||
public int Id { get; }
|
public int Id { get; }
|
||||||
public DateTime? DisconnectTime { get; set; }
|
public DateTime? DisconnectTime { get; set; }
|
||||||
|
|
||||||
public bool ShouldReconnect { get; set; }
|
public bool ShouldReconnect { get; set; }
|
||||||
|
public bool Reconnecting { get; set; }
|
||||||
|
|
||||||
public string Url { get; }
|
public string Url { get; }
|
||||||
public bool IsClosed => socket.State == WebSocketState.Closed;
|
public bool IsClosed => socket.State == WebSocketState.Closed;
|
||||||
public bool IsOpen => socket.State == WebSocketState.Open;
|
public bool IsOpen => socket.State == WebSocketState.Open;
|
||||||
@ -114,6 +117,8 @@ namespace CryptoExchange.Net.Sockets
|
|||||||
protected void CheckTimeout()
|
protected void CheckTimeout()
|
||||||
{
|
{
|
||||||
while (true)
|
while (true)
|
||||||
|
{
|
||||||
|
lock (socketLock)
|
||||||
{
|
{
|
||||||
if (socket == null || socket.State != WebSocketState.Open)
|
if (socket == null || socket.State != WebSocketState.Open)
|
||||||
return;
|
return;
|
||||||
@ -121,9 +126,10 @@ namespace CryptoExchange.Net.Sockets
|
|||||||
if (DateTime.UtcNow - LastActionTime > Timeout)
|
if (DateTime.UtcNow - LastActionTime > Timeout)
|
||||||
{
|
{
|
||||||
log.Write(LogVerbosity.Warning, $"No data received for {Timeout}, reconnecting socket");
|
log.Write(LogVerbosity.Warning, $"No data received for {Timeout}, reconnecting socket");
|
||||||
Close().Wait();
|
Close().ConfigureAwait(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Thread.Sleep(500);
|
Thread.Sleep(500);
|
||||||
}
|
}
|
||||||
@ -165,9 +171,12 @@ namespace CryptoExchange.Net.Sockets
|
|||||||
|
|
||||||
public virtual void Reset()
|
public virtual void Reset()
|
||||||
{
|
{
|
||||||
socket.Dispose();
|
lock (socketLock)
|
||||||
|
{
|
||||||
|
socket?.Dispose();
|
||||||
socket = null;
|
socket = null;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public virtual void Send(string data)
|
public virtual void Send(string data)
|
||||||
{
|
{
|
||||||
|
@ -26,6 +26,7 @@ namespace CryptoExchange.Net.Sockets
|
|||||||
|
|
||||||
private bool lostTriggered;
|
private bool lostTriggered;
|
||||||
private readonly List<SocketEvent> waitingForEvents;
|
private readonly List<SocketEvent> waitingForEvents;
|
||||||
|
private object eventLock = new object();
|
||||||
|
|
||||||
|
|
||||||
public SocketSubscription(IWebsocket socket)
|
public SocketSubscription(IWebsocket socket)
|
||||||
@ -44,8 +45,11 @@ namespace CryptoExchange.Net.Sockets
|
|||||||
Socket.DisconnectTime = DateTime.UtcNow;
|
Socket.DisconnectTime = DateTime.UtcNow;
|
||||||
lostTriggered = true;
|
lostTriggered = true;
|
||||||
|
|
||||||
|
lock (eventLock)
|
||||||
|
{
|
||||||
foreach (var events in Events)
|
foreach (var events in Events)
|
||||||
events.Reset();
|
events.Reset();
|
||||||
|
}
|
||||||
|
|
||||||
if (Socket.ShouldReconnect)
|
if (Socket.ShouldReconnect)
|
||||||
ConnectionLost?.Invoke();
|
ConnectionLost?.Invoke();
|
||||||
@ -62,10 +66,13 @@ namespace CryptoExchange.Net.Sockets
|
|||||||
|
|
||||||
public void AddEvent(string name)
|
public void AddEvent(string name)
|
||||||
{
|
{
|
||||||
|
lock (eventLock)
|
||||||
Events.Add(new SocketEvent(name));
|
Events.Add(new SocketEvent(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetEventByName(string name, bool success, Error error)
|
public void SetEventByName(string name, bool success, Error error)
|
||||||
|
{
|
||||||
|
lock (eventLock)
|
||||||
{
|
{
|
||||||
var waitingEvent = waitingForEvents.SingleOrDefault(e => e.Name == name);
|
var waitingEvent = waitingForEvents.SingleOrDefault(e => e.Name == name);
|
||||||
if (waitingEvent != null)
|
if (waitingEvent != null)
|
||||||
@ -74,8 +81,11 @@ namespace CryptoExchange.Net.Sockets
|
|||||||
waitingForEvents.Remove(waitingEvent);
|
waitingForEvents.Remove(waitingEvent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void SetEventById(string id, bool success, Error error)
|
public void SetEventById(string id, bool success, Error error)
|
||||||
|
{
|
||||||
|
lock (eventLock)
|
||||||
{
|
{
|
||||||
var waitingEvent = waitingForEvents.SingleOrDefault(e => e.WaitingId == id);
|
var waitingEvent = waitingForEvents.SingleOrDefault(e => e.WaitingId == id);
|
||||||
if (waitingEvent != null)
|
if (waitingEvent != null)
|
||||||
@ -84,50 +94,61 @@ namespace CryptoExchange.Net.Sockets
|
|||||||
waitingForEvents.Remove(waitingEvent);
|
waitingForEvents.Remove(waitingEvent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public SocketEvent GetWaitingEvent(string name)
|
public SocketEvent GetWaitingEvent(string name)
|
||||||
{
|
{
|
||||||
|
lock (eventLock)
|
||||||
return waitingForEvents.SingleOrDefault(w => w.Name == name);
|
return waitingForEvents.SingleOrDefault(w => w.Name == name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public Task<CallResult<bool>> WaitForEvent(string name, TimeSpan timeout)
|
public Task<CallResult<bool>> WaitForEvent(string name, TimeSpan timeout)
|
||||||
{
|
{
|
||||||
|
lock (eventLock)
|
||||||
return WaitForEvent(name, (int)Math.Round(timeout.TotalMilliseconds, 0));
|
return WaitForEvent(name, (int)Math.Round(timeout.TotalMilliseconds, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<CallResult<bool>> WaitForEvent(string name, int timeout)
|
public Task<CallResult<bool>> WaitForEvent(string name, int timeout)
|
||||||
|
{
|
||||||
|
lock (eventLock)
|
||||||
{
|
{
|
||||||
var evnt = Events.Single(e => e.Name == name);
|
var evnt = Events.Single(e => e.Name == name);
|
||||||
waitingForEvents.Add(evnt);
|
waitingForEvents.Add(evnt);
|
||||||
return Task.Run(() => evnt.Wait(timeout));
|
return Task.Run(() => evnt.Wait(timeout));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public Task<CallResult<bool>> WaitForEvent(string name, string id, TimeSpan timeout)
|
public Task<CallResult<bool>> WaitForEvent(string name, string id, TimeSpan timeout)
|
||||||
{
|
{
|
||||||
|
lock (eventLock)
|
||||||
return WaitForEvent(name, id, (int)Math.Round(timeout.TotalMilliseconds, 0));
|
return WaitForEvent(name, id, (int)Math.Round(timeout.TotalMilliseconds, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<CallResult<bool>> WaitForEvent(string name, string id, int timeout)
|
public Task<CallResult<bool>> WaitForEvent(string name, string id, int timeout)
|
||||||
|
{
|
||||||
|
lock (eventLock)
|
||||||
{
|
{
|
||||||
var evnt = Events.Single(e => e.Name == name);
|
var evnt = Events.Single(e => e.Name == name);
|
||||||
evnt.WaitingId = id;
|
evnt.WaitingId = id;
|
||||||
waitingForEvents.Add(evnt);
|
waitingForEvents.Add(evnt);
|
||||||
return Task.Run(() => evnt.Wait(timeout));
|
return Task.Run(() => evnt.Wait(timeout));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void ResetEvents()
|
public void ResetEvents()
|
||||||
{
|
{
|
||||||
foreach (var waiting in new List<SocketEvent>(waitingForEvents))
|
lock (eventLock)
|
||||||
|
{
|
||||||
|
foreach (var waiting in waitingForEvents)
|
||||||
waiting.Set(false, new UnknownError("Connection reset"));
|
waiting.Set(false, new UnknownError("Connection reset"));
|
||||||
waitingForEvents.Clear();
|
waitingForEvents.Clear();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public async Task Close()
|
public async Task Close()
|
||||||
{
|
{
|
||||||
Socket.ShouldReconnect = false;
|
Socket.ShouldReconnect = false;
|
||||||
await Socket.Close();
|
await Socket.Close().ConfigureAwait(false);
|
||||||
Socket.Dispose();
|
Socket.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@ namespace CryptoExchange.Net.Sockets
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public async Task Close()
|
public async Task Close()
|
||||||
{
|
{
|
||||||
await subscription.Close();
|
await subscription.Close().ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user