i2pd-tools/websocks-demo/websocks.js

138 lines
3.4 KiB
JavaScript
Raw Permalink Normal View History

2017-08-28 18:18:24 +02:00
var stream = require('stream');
2016-12-11 18:21:34 +01:00
2016-12-17 18:48:54 +01:00
2017-08-28 18:18:24 +02:00
function WebSocks(wsurl)
{
this._wsurl = wsurl;
this._ws = null;
this._ouraddr = null;
this._remoteAddr = null;
this._recvbuffer = stream.PassThrough();
this._sendbuffer = stream.PassThrough();
}
2016-12-11 18:21:34 +01:00
2017-08-28 18:18:24 +02:00
WebSocks.prototype.createListener = function(callback) {
var self = this;
self._doAccept(function(err) {
if(err) callback(err, null);
else {
callback(null, self._sendbuffer, self._recvbuffer);
2016-12-11 18:21:34 +01:00
}
2017-08-28 18:18:24 +02:00
}, function(data) {
self._recvbuffer.write(data);
});
};
WebSocks.prototype._doAccept = function(accept_cb, recv_cb) {
var self = this;
self._socket(function (err, data) {
if(!self._remoteAddr)
{
if(!data)
{
// send handshake
self._ws.send("accept");
2016-12-17 18:48:54 +01:00
}
2017-08-28 18:18:24 +02:00
else
{
// this means handshake read
var j = JSON.parse(data);
if(j.error) {
connect_cb(j.error);
} else if(j.success){
self._remoteAddr = host;
connect_cb(null);
}
// repeat
setTimeout(function() {
self._doAccept(connect_cb);
}, 10);
2016-12-17 18:48:54 +01:00
}
2016-12-11 18:21:34 +01:00
}
2017-08-28 18:18:24 +02:00
else
{
recv_cb(err, data);
2016-12-11 18:21:34 +01:00
}
2017-08-28 18:18:24 +02:00
});
};
2016-12-11 18:21:34 +01:00
2017-08-28 18:18:24 +02:00
WebSocks.prototype._closed = function()
{
var self = this;
self._recvbuffer.close();
self._sendbuffer.close();
self._ws.close();
};
WebSocks.prototype.connect = function(host, port, connect_cb) {
var self = this;
self._socket(function (err, data) {
if(!self._remoteAddr)
{
if(!data)
{
// send handshake
self._ws.send("connect "+host+":"+port);
2016-12-11 18:21:34 +01:00
}
2017-08-28 18:18:24 +02:00
else
{
// this means handshake read
var j = JSON.parse(data);
if(j.error) {
connect_cb(j.error, null, null);
} else if(j.success){
self._remoteAddr = host;
connect_cb(null, self._sendbuffer, self._recvbuffer);
2016-12-17 18:48:54 +01:00
} else {
2017-08-28 18:18:24 +02:00
connect_cb("failed to connect", null, null);
2016-12-17 18:48:54 +01:00
}
}
}
2017-08-28 18:18:24 +02:00
else
{
self._recvbuffer.write(data);
2016-12-11 18:21:34 +01:00
}
2017-08-28 18:18:24 +02:00
});
};
WebSocks.prototype._socket = function(cb) {
var self = this;
self._ws = new WebSocket(self._wsurl);
self._ws.onclose = function(ev) {
self._closed();
};
2016-12-11 18:21:34 +01:00
2017-08-28 18:18:24 +02:00
self._ws.onopen = function(ev) {
console.log("connected to websocks");
self._ws.send("getaddr");
};
2016-12-11 18:21:34 +01:00
2017-08-28 18:18:24 +02:00
self._ws.onmessage = function(ev) {
if(!self._ouraddr)
{
var j = JSON.parse(ev.data);
2016-12-11 18:21:34 +01:00
if(j.error) {
2017-08-28 18:18:24 +02:00
console.log("connect error: "+j.error);
cb(j.error, null);
return;
2016-12-11 18:21:34 +01:00
}
2017-08-28 18:18:24 +02:00
if(j.success && j.destination) {
self._ouraddr = j.destination;
} else {
cb("failed to connect", null);
return;
2016-12-11 18:21:34 +01:00
}
2017-08-28 18:18:24 +02:00
self._sendbuffer.on("data", function(data) {
self._ws.send(data);
});
cb(null, null);
2016-12-11 18:21:34 +01:00
}
2017-08-28 18:18:24 +02:00
else
cb(null, ev.data);
};
};
2016-12-11 18:21:34 +01:00
2017-08-28 18:18:24 +02:00
module.exports = {
"WebSocks": WebSocks,
};