muweb-socket
Version:
WebSocket communication for mudb
140 lines • 5.82 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
var socket_1 = require("mudb/socket");
var hasWindow = typeof window === 'object' && 'addEventListener' in window;
var WS = typeof WebSocket !== 'undefined' ? WebSocket : require.call(null, 'uws');
var MuWebSocket = (function () {
function MuWebSocket(spec) {
this.state = socket_1.MuSocketState.INIT;
this._reliableSocket = null;
this._unreliableSockets = [];
this._maxSockets = 5;
this._nextSocketSend = 0;
this.sessionId = spec.sessionId;
this._url = spec.url;
if (spec.maxSockets) {
this._maxSockets = Math.max(1, spec.maxSockets | 0);
}
}
MuWebSocket.prototype.open = function (spec) {
var _this = this;
if (this.state === socket_1.MuSocketState.OPEN) {
throw new Error('mudb/web-socket: socket already open');
}
if (this.state === socket_1.MuSocketState.CLOSED) {
throw new Error('mudb/web-socket: cannot reopen closed socket');
}
var sockets = [];
function removeSocket(socket) {
for (var i = 0; i < sockets.length; ++i) {
if (sockets[i] === socket) {
sockets.splice(i, 1);
}
}
}
if (hasWindow) {
window.addEventListener('beforeunload', function () {
for (var i = 0; i < sockets.length; ++i) {
sockets[i].close();
}
});
}
var openSocket = function () {
var socket = new WS(_this._url);
socket.binaryType = 'arraybuffer';
sockets.push(socket);
socket.onopen = function () {
socket.onmessage = function (ev) {
if (_this.state === socket_1.MuSocketState.CLOSED) {
socket.close();
return;
}
if (typeof ev.data === 'string') {
if (JSON.parse(ev.data).reliable) {
_this.state = socket_1.MuSocketState.OPEN;
socket.onmessage = function (_a) {
var data = _a.data;
if (_this.state !== socket_1.MuSocketState.OPEN) {
return;
}
if (typeof data === 'string') {
spec.message(data, false);
}
else {
spec.message(new Uint8Array(data), false);
}
};
socket.onclose = function () {
_this.state = socket_1.MuSocketState.CLOSED;
removeSocket(socket);
for (var i = 0; i < sockets.length; ++i) {
sockets[i].close();
}
spec.close();
};
_this._reliableSocket = socket;
spec.ready();
}
else {
socket.onmessage = function (_a) {
var data = _a.data;
if (_this.state !== socket_1.MuSocketState.OPEN) {
return;
}
if (typeof data === 'string') {
spec.message(data, true);
}
else {
spec.message(new Uint8Array(data), true);
}
};
socket.onclose = function () {
removeSocket(socket);
for (var i = _this._unreliableSockets.length - 1; i >= 0; --i) {
if (_this._unreliableSockets[i] === socket) {
_this._unreliableSockets.splice(i, 1);
}
}
};
_this._unreliableSockets.push(socket);
}
}
};
socket.send(JSON.stringify({
sessionId: _this.sessionId,
}));
};
};
for (var i = 0; i < this._maxSockets; ++i) {
openSocket();
}
};
MuWebSocket.prototype.send = function (data, unreliable) {
if (this.state !== socket_1.MuSocketState.OPEN) {
return;
}
if (unreliable) {
if (this._unreliableSockets.length > 0) {
this._unreliableSockets[this._nextSocketSend++ % this._unreliableSockets.length].send(data);
}
}
else if (this._reliableSocket) {
this._reliableSocket.send(data);
}
};
MuWebSocket.prototype.close = function () {
if (this.state === socket_1.MuSocketState.CLOSED) {
return;
}
this.state = socket_1.MuSocketState.CLOSED;
if (this._reliableSocket) {
this._reliableSocket.close();
}
for (var i = 0; i < this._unreliableSockets.length; ++i) {
this._unreliableSockets[i].close();
}
};
return MuWebSocket;
}());
exports.MuWebSocket = MuWebSocket;
//# sourceMappingURL=socket.js.map