You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
137 lines
3.4 KiB
137 lines
3.4 KiB
var stream = require('stream'); |
|
|
|
|
|
function WebSocks(wsurl) |
|
{ |
|
this._wsurl = wsurl; |
|
this._ws = null; |
|
this._ouraddr = null; |
|
this._remoteAddr = null; |
|
this._recvbuffer = stream.PassThrough(); |
|
this._sendbuffer = stream.PassThrough(); |
|
} |
|
|
|
WebSocks.prototype.createListener = function(callback) { |
|
var self = this; |
|
self._doAccept(function(err) { |
|
if(err) callback(err, null); |
|
else { |
|
callback(null, self._sendbuffer, self._recvbuffer); |
|
} |
|
}, 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"); |
|
} |
|
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); |
|
} |
|
} |
|
else |
|
{ |
|
recv_cb(err, data); |
|
} |
|
}); |
|
}; |
|
|
|
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); |
|
} |
|
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); |
|
} else { |
|
connect_cb("failed to connect", null, null); |
|
} |
|
} |
|
} |
|
else |
|
{ |
|
self._recvbuffer.write(data); |
|
} |
|
}); |
|
}; |
|
|
|
WebSocks.prototype._socket = function(cb) { |
|
var self = this; |
|
self._ws = new WebSocket(self._wsurl); |
|
self._ws.onclose = function(ev) { |
|
self._closed(); |
|
}; |
|
|
|
self._ws.onopen = function(ev) { |
|
console.log("connected to websocks"); |
|
self._ws.send("getaddr"); |
|
}; |
|
|
|
self._ws.onmessage = function(ev) { |
|
if(!self._ouraddr) |
|
{ |
|
var j = JSON.parse(ev.data); |
|
if(j.error) { |
|
console.log("connect error: "+j.error); |
|
cb(j.error, null); |
|
return; |
|
} |
|
if(j.success && j.destination) { |
|
self._ouraddr = j.destination; |
|
} else { |
|
cb("failed to connect", null); |
|
return; |
|
} |
|
self._sendbuffer.on("data", function(data) { |
|
self._ws.send(data); |
|
}); |
|
cb(null, null); |
|
} |
|
else |
|
cb(null, ev.data); |
|
}; |
|
}; |
|
|
|
module.exports = { |
|
"WebSocks": WebSocks, |
|
};
|
|
|