mirror of
https://github.com/adelphes/android-dev-ext.git
synced 2025-12-22 17:39:19 +00:00
123 lines
3.5 KiB
JavaScript
123 lines
3.5 KiB
JavaScript
/*
|
|
A dummy websocket implementation for passing messages internally using a WS-like protocol
|
|
*/
|
|
var Servers = {};
|
|
|
|
function isfn(x) { return typeof(x) === 'function' }
|
|
|
|
function WebSocketClient(url) {
|
|
// we only support localhost addresses in this implementation
|
|
var match = url.match(/^ws:\/\/127\.0\.0\.1:(\d+)$/);
|
|
var port = match && parseInt(match[1],10);
|
|
if (!port || port <= 0 || port >= 65536)
|
|
throw new Error('Invalid websocket url');
|
|
var server = Servers[port];
|
|
if (!server) throw new Error('Connection refused'); // 'port' already in use :)
|
|
server.addClient(this);
|
|
this._ws = {
|
|
port: port,
|
|
server: server,
|
|
outgoing:[],
|
|
};
|
|
}
|
|
|
|
WebSocketClient.prototype.send = function(message) {
|
|
this._ws.outgoing.push(message);
|
|
if (this._ws.outgoing.length > 1) return;
|
|
process.nextTick(function(client) {
|
|
if (!client || !client._ws || !client._ws.server)
|
|
return;
|
|
client._ws.server.receive(client, client._ws.outgoing);
|
|
client._ws.outgoing = [];
|
|
}, this);
|
|
}
|
|
|
|
WebSocketClient.prototype.receive = function(messages) {
|
|
if (isfn(this.onmessage))
|
|
messages.forEach(m => {
|
|
this.onmessage({
|
|
data:m
|
|
});
|
|
});
|
|
}
|
|
|
|
WebSocketClient.prototype.close = function() {
|
|
process.nextTick(() => {
|
|
this._ws.server.rmClient(this);
|
|
this._ws.server = null;
|
|
if (isfn(this.onclose))
|
|
this.onclose(this);
|
|
this._ws = null;
|
|
});
|
|
}
|
|
|
|
|
|
|
|
function WebSocketServer(port) {
|
|
if (typeof(port) !== 'number' || port <= 0 || port >= 65536)
|
|
throw new Error('Invalid websocket server port');
|
|
if (Servers[''+port])
|
|
throw new Error('Address in use');
|
|
this.port = port;
|
|
this.clients = [];
|
|
Servers[''+port] = this;
|
|
}
|
|
|
|
WebSocketServer.prototype.addClient = function(client) {
|
|
var status;
|
|
this.clients.push(status = {
|
|
server:this,
|
|
client: client,
|
|
onmessage:null,
|
|
onclose:null,
|
|
outgoing:[],
|
|
send: function(message) {
|
|
this.outgoing.push(message);
|
|
if (this.outgoing.length > 1) return;
|
|
process.nextTick(function(status) {
|
|
if (!status || !status.client)
|
|
return;
|
|
status.client.receive(status.outgoing);
|
|
status.outgoing = [];
|
|
}, this);
|
|
}
|
|
});
|
|
process.nextTick((status) => {
|
|
if (isfn(this.onconnection))
|
|
this.onconnection({
|
|
status: status,
|
|
accept:function() {
|
|
process.nextTick((status) => {
|
|
if (isfn(status.client.onopen))
|
|
status.client.onopen(status.client);
|
|
}, this.status);
|
|
return this.status;
|
|
}
|
|
});
|
|
}, status);
|
|
}
|
|
|
|
WebSocketServer.prototype.rmClient = function(client) {
|
|
for (var i = this.clients.length-1; i >= 0; --i) {
|
|
if (this.clients[i].client === client) {
|
|
if (isfn(this.clients[i].onclose))
|
|
this.clients[i].onclose();
|
|
this.clients.splice(i, 1);
|
|
}
|
|
}
|
|
}
|
|
|
|
WebSocketServer.prototype.receive = function(client, messages) {
|
|
var status = this.clients.filter(c => c.client === client)[0];
|
|
if (!status) return;
|
|
if (!isfn(status.onmessage)) return;
|
|
messages.forEach(m => {
|
|
status.onmessage({
|
|
data: m,
|
|
});
|
|
});
|
|
}
|
|
|
|
exports.WebSocketClient = WebSocketClient;
|
|
exports.WebSocketServer = WebSocketServer;
|