Files
AIGame/AIClient/Assets/Plugins/WebGL/GameWebSocket.jslib
T

98 lines
4.1 KiB
JavaScript

mergeInto(LibraryManager.library, {
$AIGameSockets: { nextId: 1, sockets: {} },
AIGame_WsCreate__deps: ['$AIGameSockets'],
AIGame_WsCreate: function (urlPointer) {
var id = AIGameSockets.nextId++;
var entry = { events: [], socket: null, disposed: false, terminal: false, wechat: false };
AIGameSockets.sockets[id] = entry;
var finish = function (kind, reason) {
if (entry.disposed || entry.terminal) return;
entry.terminal = true;
entry.events.push(kind + (reason || 'closed'));
};
var closeSocket = function () {
if (!entry.socket) return;
try {
if (entry.wechat) entry.socket.close({ code: 1000, reason: 'client close' });
else entry.socket.close(1000, 'client close');
} catch (ignored) {}
};
var opened = function () {
// WeChat may finish opening after a close requested while connecting.
if (entry.disposed || entry.terminal) { closeSocket(); return; }
entry.events.push('O');
};
var message = function (event) {
if (!entry.disposed && !entry.terminal && typeof event.data === 'string')
entry.events.push('M' + event.data);
};
try {
var url = UTF8ToString(urlPointer);
var api = typeof wx !== 'undefined' ? wx :
(typeof GameGlobal !== 'undefined' ? GameGlobal.wx : null);
if (api && api.connectSocket) {
entry.wechat = true;
var task = api.connectSocket({ url: url,
fail: function (error) { finish('E', error.errMsg || 'connectSocket failed'); } });
entry.socket = task;
task.onOpen(opened);
task.onMessage(message);
task.onError(function (error) { finish('E', error.errMsg || 'socket error'); });
task.onClose(function (event) { finish('C', String(event.code || '') + ' ' + (event.reason || 'closed')); });
} else {
var socket = new WebSocket(url);
entry.socket = socket;
socket.onopen = opened;
socket.onmessage = message;
socket.onerror = function () { finish('E', 'WebSocket connection failed'); };
socket.onclose = function (event) { finish('C', String(event.code) + ' ' + (event.reason || 'closed')); };
}
} catch (error) { finish('E', error.message || String(error)); }
return id;
},
AIGame_WsPoll__deps: ['$AIGameSockets'],
AIGame_WsPoll: function (id) {
var entry = AIGameSockets.sockets[id];
if (!entry || !entry.events.length) return 0;
var text = entry.events.shift();
var size = lengthBytesUTF8(text) + 1;
var pointer = _malloc(size);
stringToUTF8(text, pointer, size);
// IL2CPP frees the native buffer for a marshalled string return value.
return pointer;
},
AIGame_WsSend__deps: ['$AIGameSockets'],
AIGame_WsSend: function (id, textPointer) {
var entry = AIGameSockets.sockets[id];
if (!entry || entry.disposed || entry.terminal) return;
var fail = function (error) {
if (entry.disposed || entry.terminal) return;
entry.terminal = true;
entry.events.push('E' + (error.errMsg || error.message || 'send failed'));
};
try {
var text = UTF8ToString(textPointer);
if (entry.wechat) entry.socket.send({ data: text, fail: fail });
else entry.socket.send(text);
} catch (error) { fail(error); }
},
AIGame_WsDispose__deps: ['$AIGameSockets'],
AIGame_WsDispose: function (id) {
var entry = AIGameSockets.sockets[id];
if (!entry) return;
entry.disposed = true;
entry.events.length = 0;
delete AIGameSockets.sockets[id];
try {
if (entry.socket) {
if (entry.wechat) entry.socket.close({ code: 1000, reason: 'client close' });
else entry.socket.close(1000, 'client close');
}
} catch (ignored) {}
}
});