1
0
mirror of https://github.com/JKorf/CryptoExchange.Net synced 2025-06-08 16:36:15 +00:00
This commit is contained in:
JKorf 2019-01-03 08:53:02 +01:00
commit 2b1c77577c
7 changed files with 77 additions and 39 deletions

View File

@ -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();

View File

@ -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>

View File

@ -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; }

View File

@ -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

View File

@ -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)
{ {

View File

@ -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();
} }
} }

View File

@ -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);
} }
} }
} }