Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/Plugins.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

97 changes: 97 additions & 0 deletions src/Plugins/WebSocket.jslib
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
mergeInto(LibraryManager.library, {
WebSocket_Init: function(openCallback, messageCallback, closeCallback, errorCallback) {
this._webSocketManager = {
instances: {},
nextId: 1,
callbacks: {
open: null,
message: null,
close: null,
error: null
}
};

var manager = this._webSocketManager;
manager.callbacks.open = openCallback;
manager.callbacks.message = messageCallback;
manager.callbacks.close = closeCallback;
manager.callbacks.error = errorCallback;
},

WebSocket_Connect: function(uriPtr, protocolPtr, authTokenPtr) {
try {
var manager = this._webSocketManager;
var uri = UTF8ToString(uriPtr);
var protocol = UTF8ToString(protocolPtr);
var authToken = UTF8ToString(authTokenPtr);

var socket = new window.WebSocket(uri, protocol);
socket.binaryType = "arraybuffer";

var socketId = manager.nextId++;
manager.instances[socketId] = socket;

socket.onopen = function() {
if (manager.callbacks.open) {
dynCall('vi', manager.callbacks.open, [socketId]);
}
};

socket.onmessage = function(event) {
if (manager.callbacks.message && event.data instanceof ArrayBuffer) {
var buffer = _malloc(event.data.byteLength);
HEAPU8.set(new Uint8Array(event.data), buffer);
dynCall('viii', manager.callbacks.message, [socketId, buffer, event.data.byteLength]);
_free(buffer);
}
};
socket.onclose = function(event) {
if (manager.callbacks.close) {
var reasonStr = event.reason || "";
var reasonArray = intArrayFromString(reasonStr);
var reasonPtr = _malloc(reasonArray.length);
HEAP8.set(reasonArray, reasonPtr);
dynCall('viii', manager.callbacks.close, [socketId, event.code, reasonPtr]);
_free(reasonPtr);
}
delete manager.instances[socketId];
};

socket.onerror = function(error) {
if (manager.callbacks.error) {
dynCall('vi', manager.callbacks.error, [socketId]);
}
};

return socketId;
} catch (e) {
console.error("WebSocket connection error:", e);
return -1;
}
},

WebSocket_Send: function(socketId, dataPtr, length) {
var manager = this._webSocketManager;
var socket = manager.instances[socketId];
if (!socket || socket.readyState !== socket.OPEN) return -1;

try {
var data = new Uint8Array(HEAPU8.buffer, dataPtr, length);
socket.send(data);
return 0;
} catch (e) {
console.error("WebSocket send error:", e);
return -1;
}
},

WebSocket_Close: function(socketId, code, reasonPtr) {
var manager = this._webSocketManager;
var socket = manager.instances[socketId];
if (!socket) return;

var reason = UTF8ToString(reasonPtr);
socket.close(code, reason);
delete manager.instances[socketId];
}
});
3 changes: 3 additions & 0 deletions src/Plugins/WebSocket.jslib.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

39 changes: 38 additions & 1 deletion src/SpacetimeDBClient.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
Expand Down Expand Up @@ -188,10 +189,18 @@ protected DbConnectionBase()
SpacetimeDBNetworkManager._instance.RemoveConnection(this);
}
};

#if UNITY_WEBGL && !UNITY_EDITOR
if (SpacetimeDBNetworkManager._instance != null)
SpacetimeDBNetworkManager._instance.StartCoroutine(PreProcessMessages());
#endif
#endif

#if !(UNITY_WEBGL && !UNITY_EDITOR)
// For targets other than webgl we start a thread to pre-process messages
networkMessageProcessThread = new Thread(PreProcessMessages);
networkMessageProcessThread.Start();
#endif
}

struct UnprocessedMessage
Expand Down Expand Up @@ -351,10 +360,19 @@ private static IEnumerable<byte[]> BsatnRowListIter(BsatnRowList list)
};
}

#if UNITY_WEBGL && !UNITY_EDITOR
IEnumerator PreProcessMessages()
#else
void PreProcessMessages()
#endif
{
while (!isClosing)
{

#if UNITY_WEBGL && !UNITY_EDITOR
yield return null;
while (_messageQueue.Count > 0)
#endif
try
{
var message = _messageQueue.Take(_preProcessCancellationToken);
Expand All @@ -363,7 +381,11 @@ void PreProcessMessages()
}
catch (OperationCanceledException)
{
#if UNITY_WEBGL && !UNITY_EDITOR
break;
#else
return; // Normal shutdown
#endif
}
}

Expand Down Expand Up @@ -586,7 +608,13 @@ public void Disconnect()
{
isClosing = true;
connectionClosed = true;
webSocket.Close();

// Only try to close if the connection is active
if (webSocket.IsConnected)
{
webSocket.Close();
}

_preProcessCancellationTokenSource.Cancel();
}

Expand All @@ -612,7 +640,11 @@ void IDbConnection.Connect(string? token, string uri, string addressOrName, Comp
Log.Info($"SpacetimeDBClient: Connecting to {uri} {addressOrName}");
if (!IsTesting)
{
#if UNITY_WEBGL && !UNITY_EDITOR
async Task Function()
#else
Task.Run(async () =>
#endif
{
try
{
Expand All @@ -628,7 +660,12 @@ void IDbConnection.Connect(string? token, string uri, string addressOrName, Comp

Log.Exception(e);
}
#if UNITY_WEBGL && !UNITY_EDITOR
}
_ = Function();
#else
});
#endif
}
}

Expand Down
Loading
Loading