diff --git a/other/websockify.js b/other/websockify.js index cda1aaf..447fd96 100644 --- a/other/websockify.js +++ b/other/websockify.js @@ -2,9 +2,18 @@ // Copyright 2012 Joel Martin // Licensed under LGPL version 3 (see docs/LICENSE.LGPL-3) -// Known to work with node 0.6 +// Known to work with node 0.8.9 // Requires node modules: ws, base64, optimist and policyfile // npm install ws base64 optimist policyfile +// +// NOTE: +// This version requires a patched version of einaros/ws that supports +// subprotocol negotiation. You can use the patched version like this: +// +// cd websockify/other +// git clone https://github.com/kanaka/ws +// npm link ./ws + var argv = require('optimist').argv, net = require('net'), @@ -25,29 +34,48 @@ var argv = require('optimist').argv, // Handle new WebSocket client new_client = function(client) { - console.log('WebSocket client connected'); - //console.log('protocol: ' + client.protocol); + var clientAddr = client._socket.remoteAddress, log; + log = function (msg) { + console.log(' ' + clientAddr + ': '+ msg); + }; + log('WebSocket connection'); + log('Version ' + client.protocolVersion + ', subprotocol: ' + client.protocol); - var target = net.createConnection(target_port,target_host); - target.on('begin', function() { - console.log('connected to target'); + var target = net.createConnection(target_port,target_host, function() { + log('connected to target'); }); target.on('data', function(data) { - client.send(base64.encode(new Buffer(data))); + //log("sending message: " + data); + try { + if (client.protocol === 'base64') { + client.send(base64.encode(new Buffer(data))); + } else { + client.send(data,{binary: true}); + } + } catch(e) { + log("Client closed, cleaning up target"); + target.end(); + } }); target.on('end', function() { - console.log('target disconnected'); + log('target disconnected'); }); client.on('message', function(msg) { - //console.log('got some message'); - target.write(base64.decode(msg),'binary'); + //log('got message: ' + msg); + if (client.protocol === 'base64') { + target.write(base64.decode(msg),'binary'); + } else { + target.write(msg,'binary'); + } }); client.on('close', function(code, reason) { - console.log('WebSocket client disconnected: ' + code + ' [' + reason + ']'); + log('WebSocket client disconnected: ' + code + ' [' + reason + ']'); + target.end(); }); client.on('error', function(a) { - console.log('WebSocket client error: ' + a); + log('WebSocket client error: ' + a); + target.end(); }); }; @@ -131,9 +159,23 @@ if (argv.web) { console.log(" - Web server active. Serving: " + argv.web); } +function selectProtocol(protocols, callback) { + var plist = protocols ? protocols.split(',') : ""; + var plist = protocols.split(','); + if (plist.indexOf('binary') >= 0) { + callback(true, 'binary'); + } else if (plist.indexOf('base64') >= 0) { + callback(true, 'base64'); + } else { + console.log("Client must support 'binary' or 'base64' protocol"); + callback(false); + } +} + httpServer = http.createServer(http_request); httpServer.listen(source_port, function() { - wsServer = new WebSocketServer({server: httpServer}); + wsServer = new WebSocketServer({server: httpServer, + handleProtocols: selectProtocol}); wsServer.on('connection', new_client); });