Skip to content

Commit eb2b3be

Browse files
committed
fix: WebSocketException on manual reconnection after manual disconnection
1 parent 68c57de commit eb2b3be

File tree

3 files changed

+31
-11
lines changed

3 files changed

+31
-11
lines changed

src/SocketIOClient.Windows7/ClientWebSocketManaged.cs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,33 +11,43 @@ public sealed class ClientWebSocketManaged : IClientWebSocket
1111
public ClientWebSocketManaged()
1212
{
1313
_ws = new System.Net.WebSockets.Managed.ClientWebSocket();
14+
_sendLock = new SemaphoreSlim(1, 1);
1415
}
1516

1617
readonly System.Net.WebSockets.Managed.ClientWebSocket _ws;
18+
readonly SemaphoreSlim _sendLock;
1719

1820
public Action<object> ConfigOptions { get; set; }
1921

2022
public WebSocketState State => _ws.State;
2123

2224
public async Task CloseAsync(WebSocketCloseStatus closeStatus, string statusDescription, CancellationToken cancellationToken)
2325
{
24-
await _ws.CloseAsync(closeStatus, statusDescription, cancellationToken);
26+
await _ws.CloseAsync(closeStatus, statusDescription, cancellationToken).ConfigureAwait(false);
2527
}
2628

2729
public async Task ConnectAsync(Uri uri, CancellationToken cancellationToken)
2830
{
2931
ConfigOptions?.Invoke(_ws.Options);
30-
await _ws.ConnectAsync(uri, cancellationToken);
32+
await _ws.ConnectAsync(uri, cancellationToken).ConfigureAwait(false);
3133
}
3234

3335
public async Task<WebSocketReceiveResult> ReceiveAsync(ArraySegment<byte> buffer, CancellationToken cancellationToken)
3436
{
35-
return await _ws.ReceiveAsync(buffer, cancellationToken);
37+
return await _ws.ReceiveAsync(buffer, cancellationToken).ConfigureAwait(false);
3638
}
3739

3840
public async Task SendAsync(ArraySegment<byte> buffer, WebSocketMessageType messageType, bool endOfMessage, CancellationToken cancellationToken)
3941
{
40-
await _ws.SendAsync(buffer, messageType, endOfMessage, cancellationToken);
42+
try
43+
{
44+
await _sendLock.WaitAsync().ConfigureAwait(false);
45+
await _ws.SendAsync(buffer, messageType, endOfMessage, cancellationToken).ConfigureAwait(false);
46+
}
47+
finally
48+
{
49+
_sendLock.Release();
50+
}
4151
}
4252

4353
public void Dispose()

src/SocketIOClient/Transport/DefaultClientWebSocket.cs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,33 +10,43 @@ public class DefaultClientWebSocket : IClientWebSocket
1010
public DefaultClientWebSocket()
1111
{
1212
_ws = new ClientWebSocket();
13+
_sendLock = new SemaphoreSlim(1, 1);
1314
}
1415

1516
readonly ClientWebSocket _ws;
17+
readonly SemaphoreSlim _sendLock;
1618

1719
public Action<object> ConfigOptions { get; set; }
1820

1921
public WebSocketState State => _ws.State;
2022

2123
public async Task CloseAsync(WebSocketCloseStatus closeStatus, string statusDescription, CancellationToken cancellationToken)
2224
{
23-
await _ws.CloseAsync(closeStatus, statusDescription, cancellationToken);
25+
await _ws.CloseAsync(closeStatus, statusDescription, cancellationToken).ConfigureAwait(false);
2426
}
2527

2628
public async Task ConnectAsync(Uri uri, CancellationToken cancellationToken)
2729
{
2830
ConfigOptions?.Invoke(_ws.Options);
29-
await _ws.ConnectAsync(uri, cancellationToken);
31+
await _ws.ConnectAsync(uri, cancellationToken).ConfigureAwait(false);
3032
}
3133

3234
public async Task<WebSocketReceiveResult> ReceiveAsync(ArraySegment<byte> buffer, CancellationToken cancellationToken)
3335
{
34-
return await _ws.ReceiveAsync(buffer, cancellationToken);
36+
return await _ws.ReceiveAsync(buffer, cancellationToken).ConfigureAwait(false);
3537
}
3638

3739
public async Task SendAsync(ArraySegment<byte> buffer, WebSocketMessageType messageType, bool endOfMessage, CancellationToken cancellationToken)
3840
{
39-
await _ws.SendAsync(buffer, messageType, endOfMessage, cancellationToken);
41+
try
42+
{
43+
await _sendLock.WaitAsync().ConfigureAwait(false);
44+
await _ws.SendAsync(buffer, messageType, endOfMessage, cancellationToken).ConfigureAwait(false);
45+
}
46+
finally
47+
{
48+
_sendLock.Release();
49+
}
4050
}
4151

4252
public void Dispose()

src/SocketIOClient/Transport/TransportRouter.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -134,13 +134,13 @@ private void StartPolling()
134134
}, TaskCreationOptions.LongRunning);
135135
}
136136

137-
private void OnWebSocketTextReceived(string text)
137+
private async void OnWebSocketTextReceived(string text)
138138
{
139139
if (text == "3probe")
140140
{
141141
var msg = new ConnectedMessage { Namespace = Namespace, Sid = Sid };
142-
_ = _webSocketTransport.SendAsync("5", CancellationToken.None);
143-
_ = _webSocketTransport.SendAsync(msg.Write(), CancellationToken.None);
142+
await _webSocketTransport.SendAsync("5", CancellationToken.None);
143+
await _webSocketTransport.SendAsync(msg.Write(), CancellationToken.None);
144144
}
145145
else
146146
{

0 commit comments

Comments
 (0)