// WebSocket bridge for the Rudder Unity SDK (JsWebSocketAdapter). // Implements the __Internal__ externals declared in Realtime/JsWebSocketAdapter.cs: // RudderWebSocketCreate(gameObjectName, url) // RudderWebSocketSend(gameObjectName, data, length) // RudderWebSocketClose(gameObjectName) // Events are routed back to the bridge GameObject via SendMessage: // OnOpen(string), OnMessage(string base64), OnClose(string), OnError(string) var RudderWebSockets = {}; function RudderWebSocketBase64(bytes) { var chunks = []; var chunkSize = 0x8000; for (var i = 0; i < bytes.length; i += chunkSize) { chunks.push(String.fromCharCode.apply(null, bytes.subarray(i, i + chunkSize))); } return btoa(chunks.join('')); } mergeInto(LibraryManager.library, { RudderWebSocketCreate: function (gameObjectName, url) { var name = UTF8ToString(gameObjectName); var socket = new WebSocket(UTF8ToString(url)); socket.binaryType = 'arraybuffer'; RudderWebSockets[name] = socket; socket.onopen = function () { SendMessage(name, 'OnOpen', 'opened'); }; socket.onmessage = function (event) { var bytes; if (typeof event.data === 'string') { // Text frame: UTF-8 encode, then base64 (the C# side decodes base64 to bytes). bytes = new TextEncoder().encode(event.data); } else { bytes = new Uint8Array(event.data); } SendMessage(name, 'OnMessage', RudderWebSocketBase64(bytes)); }; socket.onerror = function () { SendMessage(name, 'OnError', 'WebSocket error'); }; socket.onclose = function () { delete RudderWebSockets[name]; SendMessage(name, 'OnClose', 'closed'); }; }, RudderWebSocketSend: function (gameObjectName, data, length) { var socket = RudderWebSockets[UTF8ToString(gameObjectName)]; if (!socket || socket.readyState !== WebSocket.OPEN) return; socket.send(HEAPU8.subarray(data, data + length)); }, RudderWebSocketClose: function (gameObjectName) { var name = UTF8ToString(gameObjectName); var socket = RudderWebSockets[name]; if (socket) { delete RudderWebSockets[name]; socket.close(); } } });