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, };