Skip to content

Instantly share code, notes, and snippets.

@theturtle32
Created July 20, 2011 05:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save theturtle32/1094399 to your computer and use it in GitHub Desktop.
Save theturtle32/1094399 to your computer and use it in GitHub Desktop.
Proof of Concept Integration of Socket.IO and WebSocket-Node
{
"name": "socket.io"
, "version": "0.7.7"
, "description": "Real-time apps made cross-browser & easy with a WebSocket-like API"
, "homepage": "http://socket.io"
, "keywords": ["websocket", "socket", "realtime", "socket.io", "comet", "ajax"]
, "author": "Guillermo Rauch <guillermo@learnboost.com>"
, "contributors": [
{ "name": "Guillermo Rauch", "email": "rauchg@gmail.com" }
, { "name": "Arnout Kazemier", "email": "info@3rd-eden.com" }
, { "name": "Vladimir Dronnikov", "email": "dronnikov@gmail.com" }
]
, "repository":{
"type": "git"
, "url": "https://github.com/LearnBoost/Socket.IO-node.git"
}
, "dependencies": {
"socket.io-client": "0.7.4"
, "policyfile": "0.0.3"
, "redis": "0.6.5"
, "websocket": ">=0.0.13"
}
, "devDependencies": {
"expresso": "0.7.7"
, "should": "0.0.4"
}
, "main": "index"
, "engines": { "node": ">= 0.4.0" }
}
/*!
* socket.io-node
* Copyright(c) 2011 LearnBoost <dev@learnboost.com>
* MIT Licensed
*/
/**
* Module requirements.
*/
var Transport = require('../transport')
, EventEmitter = process.EventEmitter
, crypto = require('crypto')
, parser = require('../parser')
, WebSocketRequest = require('websocket').request;
/**
* Export the constructor.
*/
exports = module.exports = WebSocket;
/**
* HTTP interface constructor. Interface compatible with all transports that
* depend on request-response cycles.
*
* @api public
*/
function WebSocket (mng, data, req) {
// parser
var self = this;
this.websocketConfig = {
// 64KiB max frame size.
maxReceivedFrameSize: 0x10000,
// 1MiB max message size, only applicable if
// assembleFragments is true
maxReceivedMessageSize: 0x100000,
// Outgoing messages larger than fragmentationThreshold will be
// split into multiple fragments.
fragmentOutgoingMessages: false,
// Outgoing frames are fragmented if they exceed this threshold.
// Default is 16KiB
fragmentationThreshold: 0x4000,
// If true, the server will automatically send a ping to all
// clients every 'keepaliveInterval' milliseconds.
keepalive: false,
// The interval to send keepalive pings to connected clients.
keepaliveInterval: 20000,
// If true, fragmented messages will be automatically assembled
// and the full message will be emitted via a 'message' event.
// If false, each frame will be emitted via a 'frame' event and
// the application will be responsible for aggregating multiple
// fragmented frames. Single-frame messages will emit a 'message'
// event in addition to the 'frame' event.
// Most users will want to leave this set to 'true'
assembleFragments: true,
// The number of milliseconds to wait after sending a close frame
// for an acknowledgement to come back before giving up and just
// closing the socket.
closeTimeout: 5000
};
Transport.call(this, mng, data, req);
};
/**
* Inherits from Transport.
*/
WebSocket.prototype.__proto__ = Transport.prototype;
/**
* Transport name
*
* @api public
*/
WebSocket.prototype.name = 'websocket';
/**
* Called when the socket connects.
*
* @api private
*/
WebSocket.prototype.onSocketConnect = function () {
var self = this;
this.socket.setNoDelay(true);
this.buffer = true;
this.buffered = [];
try {
var wsRequest = new WebSocketRequest(this.socket, this.req, this.websocketConfig);
}
catch(e) {
this.log.warn(this.name + ' connection invalid: ' + e.toString());
this.end();
return;
}
// TODO: Make the cross-origin and protocol handling secure
try {
var wsConnection = wsRequest.accept(null, wsRequest.origin);
}
catch(e) {
this.log.warn(this.name + ' websocket connect error: ' + e.toString());
}
this.wsConnection = wsConnection;
this.flush();
wsConnection.on('message', function(message) {
if (message.type === 'utf8') {
self.onMessage(parser.decodePacket(message.utf8Data));
}
else if (message.type === 'binary') {
self.log.warn(self.name + ' unsupported websocket binary message received.');
}
});
wsConnection.on('close', function() {
self.onClose();
});
wsConnection.on('error', function(error) {
self.log.warn(self.name + ' connection error: ' + error);
});
};
/**
* Writes to the socket.
*
* @api private
*/
WebSocket.prototype.write = function (data) {
if (this.open) {
this.drained = false;
if (this.buffer) {
this.buffered.push(data);
return this;
}
this.wsConnection.sendUTF(data);
this.drained = true;
this.log.debug(this.name + ' writing', data);
}
};
/**
* Flushes the internal buffer
*
* @api private
*/
WebSocket.prototype.flush = function () {
this.buffer = false;
for (var i = 0, l = this.buffered.length; i < l; i++) {
this.write(this.buffered.splice(0, 1)[0]);
}
};
/**
* Writes a payload.
*
* @api private
*/
WebSocket.prototype.payload = function (msgs) {
for (var i = 0, l = msgs.length; i < l; i++) {
this.write(msgs[i]);
}
return this;
};
/**
* Closes the connection.
*
* @api private
*/
WebSocket.prototype.doClose = function () {
this.wsConnection.close();
};
@theturtle32
Copy link
Author

This shows integration between Socket.IO and WebSocket-Node

https://github.com/LearnBoost/socket.io

https://github.com/Worlize/WebSocket-Node

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