Skip to content

Instantly share code, notes, and snippets.

@nicokaiser
Created September 15, 2011 12:54
  • Star 5 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save nicokaiser/1219165 to your computer and use it in GitHub Desktop.
WebSocket library fallback for old protocol clients
#!/usr/bin/env node
// Example of how to fallback to alternative websocket library for old protocol clients
// see https://gist.github.com/1148686
var http = require('http'),
WebSocketRequest = require('websocket').request,
ws = require('websocket-server');
var httpServer = http.createServer(function(request, response) {
console.log((new Date()) + " Received request for " + request.url);
response.writeHead(404);
response.end();
});
httpServer.listen(10080, function() {
console.log((new Date()) + " Server is listening on port 10080");
});
// node-websocket-server
var miksagoConnection = require('./node_modules/websocket-server/lib/ws/connection');
var miksagoServer = ws.createServer();
miksagoServer.server = httpServer;
miksagoServer.addListener('connection', function(connection) {
// Add remoteAddress property
connection.remoteAddress = connection._socket.remoteAddress;
// We want to use "sendUTF" regardless of the server implementation
connection.sendUTF = connection.send;
handleConnection(connection);
});
// WebSocket-Node config
var wsServerConfig = {
// All options *except* 'httpServer' are required when bypassing
// WebSocketServer.
maxReceivedFrameSize: 0x10000,
maxReceivedMessageSize: 0x100000,
fragmentOutgoingMessages: true,
fragmentationThreshold: 0x4000,
keepalive: true,
keepaliveInterval: 20000,
assembleFragments: true,
// autoAcceptConnections is not applicable when bypassing WebSocketServer
// autoAcceptConnections: false,
disableNagleAlgorithm: true,
closeTimeout: 5000
};
// Handle the upgrade event ourselves instead of using WebSocketServer
httpServer.on('upgrade', function(req, socket, head) {
if (typeof req.headers['sec-websocket-version'] !== 'undefined') {
// WebSocket hybi-08/-09/-10 connection (WebSocket-Node)
var wsRequest = new WebSocketRequest(socket, req, wsServerConfig);
try {
wsRequest.readHandshake();
var wsConnection = wsRequest.accept(wsRequest.requestedProtocols[0], wsRequest.origin);
handleConnection(wsConnection);
}
catch(e) {
console.log("WebSocket Request unsupported by WebSocket-Node: " + e.toString());
return;
}
} else {
// WebSocket hixie-75/-76/hybi-00 connection (node-websocket-server)
if (req.method === 'GET' &&
(req.headers.upgrade && req.headers.connection) &&
req.headers.upgrade.toLowerCase() === 'websocket' &&
req.headers.connection.toLowerCase() === 'upgrade') {
new miksagoConnection(miksagoServer.manager, miksagoServer.options, req, socket, head);
}
}
});
// A common connection handler
function handleConnection(connection) {
console.log((new Date()) + " Connection accepted.");
connection.addListener('message', function(wsMessage) {
var message = wsMessage;
// WebSocket-Node adds a "type", node-websocket-server does not
if (typeof wsMessage.type !== 'undefined') {
if (wsMessage.type !== 'utf8') {
return;
}
message = wsMessage.utf8Data;
}
console.log("Received Message: " + message);
connection.sendUTF(message);
});
connection.addListener('close', function() {
console.log((new Date()) + " Peer " + connection.remoteAddress + " disconnected.");
});
}
@nicokaiser
Copy link
Author

Requiring the connection object from the node_modules directory is not nice, but it's the only solution I see for this...

@dvv
Copy link

dvv commented Sep 15, 2011

Great!

@dvv
Copy link

dvv commented Sep 15, 2011

I'd better reverse the direction of shim at L67 wsConnection.send = wsConnection.sendUTF; to be wsConnection.sendUTF = wsConnection.send; inside of fallback handler

@nicokaiser
Copy link
Author

@dvv: You are right, I changed the code.

@theturtle32
Copy link

Nice! Impressive bit of hackery. It's unfortunate that such things are necessary at the moment. :-/ Hopefully we can converge on something more universal soon. With the amount of complexity that's in the WebSocket protocol now, it's truly unfortunate that multiple drafts must be supported. It's a rather large maintenance undertaking: find a bug in the protocol layer and it'll likely need to be fixed in three or more copies of the same code, each targeting a different protocol draft. :-(

@seawing
Copy link

seawing commented Sep 23, 2011

i have a question, it is normal that a connexion with node-websocket kick all connexion with websocket-server? (i need this two websocket because of chrome update)
sorry for my bad english and if i don't post on the right place

@theturtle32
Copy link

I updated the README at https://github.com/Worlize/WebSocket-Node to reference this gist. Hopefully others will find it helpful also.

@nicokaiser
Copy link
Author

@seawing What exactly do you mean? Connections for WebSocket-Node and nws should be possible side-by-side, whatever the clients wants.

@toshirot
Copy link

toshirot commented Dec 1, 2011

I added the broadcast. I hope that iphone to be support the new protocol. http://socketapi.com/jsbu/20111126/1076/wsserver.js

@theturtle32
Copy link

theturtle32 commented Dec 2, 2011 via email

@toshirot
Copy link

toshirot commented Dec 4, 2011

I forked:) https://gist.github.com/1428579
Best regards

@theturtle32
Copy link

Thanks, updated the README on the WebSocket-Node page.

@wcauchois
Copy link

Hey, thanks for this! If anyone's interested, I turned this code into a library that emulates the node-websocket-server API but under the hood uses whichever implementation is appropriate. Feel free to check it out here: https://github.com/wcauchois/websocket-fallback.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment