Skip to content

Commit

Permalink
fix: Websockets Transport now handles being disabled for scene change…
Browse files Browse the repository at this point in the history
…s (#1994)

* fix: Websockets Transport now handles being disabled for scene changes

* Removed unused method

* Removed test warnings

* Changed back to await Task.Run

* adding queue to ClientJs

keeping standalone client without queue
dont need common class for now as that over complicates the fix

Co-authored-by: Chris Langsenkamp <chris@clevertech.net>
  • Loading branch information
James-Frowen and Chris Langsenkamp committed Jun 13, 2020
1 parent 7e2b733 commit 5480a58
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 8 deletions.
15 changes: 15 additions & 0 deletions Assets/Mirror/Runtime/Transport/Websocket/Client.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ public async void Connect(Uri uri)
}
}

public bool enabled;

async Task ReceiveLoop(WebSocket webSocket, CancellationToken token)
{
byte[] buffer = new byte[MaxMessageSize];
Expand All @@ -87,6 +89,8 @@ async Task ReceiveLoop(WebSocket webSocket, CancellationToken token)
{
WebSocketReceiveResult result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), token);

await Task.Run(WaitForEnabled);

if (result == null)
break;
if (result.MessageType == WebSocketMessageType.Close)
Expand All @@ -109,6 +113,17 @@ async Task ReceiveLoop(WebSocket webSocket, CancellationToken token)
}
}

void WaitForEnabled()
{
while (!enabled) { Task.Delay(10); }
}

public bool ProcessClientMessage()
{
// message in standalone client don't use queue to process
return false;
}

// a message might come splitted in multiple frames
// collect all frames
async Task<ArraySegment<byte>> ReadFrames(WebSocketReceiveResult result, WebSocket webSocket, byte[] buffer)
Expand Down
24 changes: 16 additions & 8 deletions Assets/Mirror/Runtime/Transport/Websocket/ClientJs.cs
Original file line number Diff line number Diff line change
@@ -1,17 +1,11 @@
#if UNITY_WEBGL && !UNITY_EDITOR

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Net.WebSockets;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using AOT;
using Ninja.WebSockets;
using UnityEngine;

namespace Mirror.Websocket
{
Expand All @@ -28,6 +22,9 @@ public class Client
public event Action Disconnected;
public event Action<Exception> ReceivedError;

readonly ConcurrentQueue<byte[]> receivedQueue = new ConcurrentQueue<byte[]>();

public bool enabled;
public bool Connecting { get; set; }
public bool IsConnected
{
Expand Down Expand Up @@ -65,6 +62,17 @@ public void Send(ArraySegment<byte> segment)
SocketSend(nativeRef, segment.Array, segment.Count);
}

public bool ProcessClientMessage()
{
if (receivedQueue.TryDequeue(out byte[] data))
{
clients[id].ReceivedData(new ArraySegment<byte>(data));

return true;
}
return false;
}

#region Javascript native functions
[DllImport("__Internal")]
static extern int SocketCreate(
Expand Down Expand Up @@ -108,7 +116,7 @@ public static void OnData(int id, IntPtr ptr, int length)
byte[] data = new byte[length];
Marshal.Copy(ptr, data, 0, length);

clients[id].ReceivedData(new ArraySegment<byte>(data));
clients[id].receivedQueue.Enqueue(data);
}
#endregion
}
Expand Down
9 changes: 9 additions & 0 deletions Assets/Mirror/Runtime/Transport/Websocket/Server.cs
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,8 @@ bool CertVerificationCallback(object sender, X509Certificate certificate, X509Ch
return true;
}

public bool enabled;

async Task ReceiveLoopAsync(WebSocket webSocket, CancellationToken token)
{
int connectionId = NextConnectionId();
Expand All @@ -194,6 +196,8 @@ async Task ReceiveLoopAsync(WebSocket webSocket, CancellationToken token)
{
WebSocketReceiveResult result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), token);

await Task.Run(WaitForEnabled);

if (result.MessageType == WebSocketMessageType.Close)
{
Debug.Log($"Client initiated close. Status: {result.CloseStatus} Description: {result.CloseStatusDescription}");
Expand Down Expand Up @@ -228,6 +232,11 @@ async Task ReceiveLoopAsync(WebSocket webSocket, CancellationToken token)
}
}

void WaitForEnabled()
{
while (!enabled) { Task.Delay(10); }
}

// a message might come splitted in multiple frames
// collect all frames
async Task<ArraySegment<byte>> ReadFrames(int connectionId, WebSocketReceiveResult result, WebSocket webSocket, byte[] buffer, CancellationToken token)
Expand Down
39 changes: 39 additions & 0 deletions Assets/Mirror/Runtime/Transport/Websocket/WebsocketTransport.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,45 @@ public override bool Available()
return true;
}

void OnEnable()
{
server.enabled = true;
client.enabled = true;
}

void OnDisable()
{
server.enabled = false;
client.enabled = false;
}

void LateUpdate()
{
// note: we need to check enabled in case we set it to false
// when LateUpdate already started.
// (https://github.com/vis2k/Mirror/pull/379)
if (!enabled)
return;

// process a maximum amount of client messages per tick
// TODO add clientMaxReceivesPerTick same as telepathy
while (true)
{
// stop when there is no more message
if (!client.ProcessClientMessage())
{
break;
}

// Some messages can disable transport
// If this is disabled stop processing message in queue
if (!enabled)
{
break;
}
}
}

// client
public override bool ClientConnected() => client.IsConnected;

Expand Down

0 comments on commit 5480a58

Please sign in to comment.