Skip to content

Commit

Permalink
fix(websocket): #829 fix InvalidOperationException with wss:// (#830)
Browse files Browse the repository at this point in the history
* fix(wss): Use a queue on the server to avoid "InvalidOperationException: Invalid nested call."

* Remove unnecessary "private"

Co-Authored-By: Katori <znorth@gmail.com>

* Remove unnecessary "private"

Co-Authored-By: Katori <znorth@gmail.com>

* Update Server.cs

* comment: explain what is going on here

* comments:  better comment

* Move queue into WebSocketImplementation instead of Server-specific

* Remove unused variables in Server

* Use a SemaphoreSlim instead of queue system
  • Loading branch information
Katori authored and vis2k committed Apr 21, 2019
1 parent 9704cfb commit 2d682b5
Showing 1 changed file with 18 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ internal class WebSocketImplementation : WebSocket
const int MAX_PING_PONG_PAYLOAD_LEN = 125;
WebSocketCloseStatus? _closeStatus;
string _closeStatusDescription;
SemaphoreSlim sendSemaphore = new SemaphoreSlim(1, 1);

public event EventHandler<PongEventArgs> Pong;

Expand Down Expand Up @@ -217,6 +218,23 @@ public override async Task<WebSocketReceiveResult> ReceiveAsync(ArraySegment<byt
/// If it is a multi-part message then false (and true for the last message)</param>
/// <param name="cancellationToken">the cancellation token</param>
public override async Task SendAsync(ArraySegment<byte> buffer, WebSocketMessageType messageType, bool endOfMessage, CancellationToken cancellationToken)
{
// workaround for: https://forum.unity.com/threads/unity-2017-1-tls-1-2-still-not-working-with-net-4-6.487415/
// In SslStream, only one SendAsync can be going at a time
// if Send is called multiple time, only the first one calls SendAsync,
// the other ones queue up the message
await sendSemaphore.WaitAsync();
try
{
await SendAsyncInternal(buffer, messageType, endOfMessage, cancellationToken);
}
finally
{
sendSemaphore.Release();
}
}

private async Task SendAsyncInternal(ArraySegment<byte> buffer, WebSocketMessageType messageType, bool endOfMessage, CancellationToken cancellationToken)
{
using (MemoryStream stream = _recycledStreamFactory())
{
Expand Down

0 comments on commit 2d682b5

Please sign in to comment.