Skip to content

Instantly share code, notes, and snippets.

@groundwater
Created May 28, 2013 04:57
Show Gist options
  • Save groundwater/5660599 to your computer and use it in GitHub Desktop.
Save groundwater/5660599 to your computer and use it in GitHub Desktop.
var http = require('http');
var crypto = require('crypto');
var PORT = process.env.PORT || 8888;
var MAGIC_STRING = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11';
function Frame(buffer){
this.buffer = buffer;
// header
// 128 = text-message
// 1 = end-frame
// 128 + 1 = complete text frame
this.buffer.writeUInt8(129,0);
this.length = 0;
}
Frame.prototype.prepare = function(msg){
this.length = msg.length;
// write the message to the data section
// of the frame, utf-8 encoded
this.buffer.write(msg,2);
// encode message length,
// if this is over 127, we need to use the
// extended protocol, which we don't support
this.buffer.writeUInt8(this.length,1);
}
Frame.prototype.write = function(){
return this.buffer.slice(0,this.length + 2);
}
// send buffer
var frame = new Frame(
// create a large buffer to handle all
// outgoing messages, it will be re-used
new Buffer(Array(150))
);
http.createServer()
.on('upgrade', function(req, socket) {
console.log('Upgrading to WebSocket Connection');
socket.on('close',function(){
console.log('socket closed');
});
socket.on('data',function(data){
// mask octets
// these are random, and set by the client
var mask = [
data.readUInt8(2),
data.readUInt8(3),
data.readUInt8(4),
data.readUInt8(5)
];
// we assume all messages are of length
// of <127 otherwise our protocol needs to be
// smarter
// decode incoming data
for(var i=0; i<data.length-6; i++){
// data is overwritten with decoded message
var msg = data.readUInt8( i + 6 );
data.writeUInt8(
// XOR the incomign message with the
// appropriate bit mask
msg^mask[i % 4], i + 6
);
}
// Capture the string portion of the message
var reply = data.slice(6).toString('utf-8');
console.log(reply);
// Write the reply back to the socket
frame.prepare('PONG:' + reply);
socket.write( frame.write() );
});
// Server Handshake
// there is no error handling
// Calculate server response key
var key = req.headers['sec-websocket-key'];
var shasum = crypto.createHash('sha1');
shasum.update(key);
shasum.update(MAGIC_STRING);
var dig = shasum.digest('base64');
out = [
'HTTP/1.1 101 Switching Protocols',
'Upgrade: WebSocket',
'Connection: Upgrade',
'Sec-WebSocket-Accept: ' + dig,
''
];
for( i in out ){
socket.write(out[i]);
socket.write('\r\n')
}
})
.listen(PORT);
console.log("WebSocket Server Listening on Port %d",PORT);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment