Created
May 28, 2013 04:57
-
-
Save groundwater/5660599 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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