Skip to content

Commit cafbccb

Browse files
authored
Merge pull request #159 from frco9/bugfix/158-no-disconnect-on-poor-connection
fix: Catch websocket exception to detect disconnection & lock Emit to prevent race condition on OutgoingBytes
2 parents 5bd7593 + c2a2e64 commit cafbccb

File tree

2 files changed

+58
-14
lines changed

2 files changed

+58
-14
lines changed

src/SocketIOClient/Processors/PingProcessor.cs

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Diagnostics;
23

34
namespace SocketIOClient.Processors
45
{
@@ -8,10 +9,22 @@ public override async void Process(MessageContext ctx)
89
{
910
if (ctx.SocketIO.Options.EIO == 4)
1011
{
11-
ctx.SocketIO.InvokePing();
12-
DateTime pingTime = DateTime.Now;
13-
await ctx.SocketIO.Socket.SendMessageAsync("3");
14-
ctx.SocketIO.InvokePong(DateTime.Now - pingTime);
12+
try
13+
{
14+
ctx.SocketIO.InvokePing();
15+
DateTime pingTime = DateTime.Now;
16+
await ctx.SocketIO.Socket.SendMessageAsync("3");
17+
ctx.SocketIO.InvokePong(DateTime.Now - pingTime);
18+
}
19+
catch (System.Net.WebSockets.WebSocketException e)
20+
{
21+
ctx.SocketIO.InvokeDisconnect(e.Message);
22+
}
23+
catch (Exception ex)
24+
{
25+
Trace.TraceError(ex.ToString());
26+
}
27+
1528
}
1629
}
1730
}

src/SocketIOClient/SocketIO.cs

Lines changed: 41 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using SocketIOClient.ConnectInterval;
22
using SocketIOClient.EioHandler;
33
using SocketIOClient.EventArguments;
4+
using SocketIOClient.Exceptions;
45
using SocketIOClient.JsonSerializer;
56
using SocketIOClient.Response;
67
using SocketIOClient.WebSocketClient;
@@ -112,6 +113,8 @@ public Uri ServerUri
112113

113114
public IJsonSerializer JsonSerializer { get; set; }
114115

116+
static readonly SemaphoreSlim _semaphoreSlim = new SemaphoreSlim(1, 1);
117+
115118
#region Socket.IO event
116119
public event EventHandler OnConnected;
117120
//public event EventHandler<string> OnConnectError;
@@ -299,15 +302,27 @@ private async Task EmityCoreAsync(string eventName, int packetId, string data, C
299302
}
300303
builder.Append(']');
301304
string message = builder.ToString();
302-
await Socket.SendMessageAsync(message, cancellationToken);
303-
if (OutGoingBytes.Count > 0)
305+
try
304306
{
305-
foreach (var item in OutGoingBytes)
307+
await Socket.SendMessageAsync(message, cancellationToken);
308+
if (OutGoingBytes.Count > 0)
306309
{
307-
await Socket.SendMessageAsync(item, cancellationToken);
310+
foreach (var item in OutGoingBytes)
311+
{
312+
await Socket.SendMessageAsync(item, cancellationToken);
313+
}
314+
OutGoingBytes.Clear();
308315
}
309-
OutGoingBytes.Clear();
310316
}
317+
catch (System.Net.WebSockets.WebSocketException e)
318+
{
319+
this.InvokeDisconnect(e.Message);
320+
}
321+
catch (InvalidSocketStateException e)
322+
{
323+
this.InvokeDisconnect(e.Message);
324+
}
325+
311326
}
312327

313328
internal async Task EmitCallbackAsync(int packetId, params object[] data)
@@ -364,8 +379,16 @@ public async Task EmitAsync(string eventName, params object[] data)
364379

365380
public async Task EmitAsync(string eventName, CancellationToken cancellationToken, params object[] data)
366381
{
367-
string dataString = GetDataString(data);
368-
await EmityCoreAsync(eventName, -1, dataString, cancellationToken);
382+
await _semaphoreSlim.WaitAsync();
383+
try
384+
{
385+
string dataString = GetDataString(data);
386+
await EmityCoreAsync(eventName, -1, dataString, cancellationToken);
387+
}
388+
finally
389+
{
390+
_semaphoreSlim.Release();
391+
}
369392
}
370393

371394
/// <summary>
@@ -382,9 +405,17 @@ public async Task EmitAsync(string eventName, Action<SocketIOResponse> ack, para
382405

383406
public async Task EmitAsync(string eventName, CancellationToken cancellationToken, Action<SocketIOResponse> ack, params object[] data)
384407
{
385-
Acks.Add(++PacketId, ack);
386-
string dataString = GetDataString(data);
387-
await EmityCoreAsync(eventName, PacketId, dataString, cancellationToken);
408+
await _semaphoreSlim.WaitAsync();
409+
try
410+
{
411+
Acks.Add(++PacketId, ack);
412+
string dataString = GetDataString(data);
413+
await EmityCoreAsync(eventName, PacketId, dataString, cancellationToken);
414+
}
415+
finally
416+
{
417+
_semaphoreSlim.Release();
418+
}
388419
}
389420

390421
internal void Open(OpenResponse openResponse)

0 commit comments

Comments
 (0)