-
-
Notifications
You must be signed in to change notification settings - Fork 37
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Original code from sockjs-node/examples/multiplex commit 5481094b322541e5976b3577b87b82031c824645
- Loading branch information
0 parents
commit f7a346d
Showing
11 changed files
with
448 additions
and
0 deletions.
There are no files selected for viewing
This file contains 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
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,2 @@ | |||
examples/sockjs/node_modules | |||
|
This file contains 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
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,20 @@ | |||
all: | |||
|
|||
VER:=$(shell ./VERSION-GEN) | |||
MAJVER:=$(shell echo $(VER)|sed 's|^\([^.]\+[.][^.]\+\).*$$|\1|' ) | |||
|
|||
CLIENT_ARTIFACTS=\ | |||
websocket-multiplex-$(VER).js \ | |||
websocket-multiplex-$(MAJVER).js | |||
|
|||
upload_client: | |||
echo "VER=$(VER) MAJVER=$(MAJVER)" | |||
cp multiplex_client.js websocket-multiplex-$(VER).js | |||
cp multiplex_client.js websocket-multiplex-$(MAJVER).js | |||
@echo -e 'Run:' | |||
@echo -e '\ts3cmd put --acl-public index.html $(CLIENT_ARTIFACTS) s3://sockjs' | |||
@echo -e '\tmake clean' | |||
|
|||
clean: | |||
rm $(CLIENT_ARTIFACTS) | |||
rm -rf examples/sockjs/node_modules |
This file contains 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
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,68 @@ | |||
|
|||
WebSocket-multiplex | |||
=================== | |||
|
|||
WebSocket-multiplex is a small library on top of SockJS that allows | |||
you to do multiplexing over a single SockJS connection. | |||
|
|||
The rationale for that is explained in details in the following blog | |||
post: | |||
|
|||
* https://www.rabbitmq.com/blog/2012/02/23/how-to-compose-apps-using-websockets/ | |||
|
|||
|
|||
Usage from the browser | |||
---------------------- | |||
|
|||
On the client side (browser) load library like that: | |||
|
|||
<script src="http://cdn.sockjs.org/websocket-multiplex-0.1.js"> | |||
</script> | |||
|
|||
Alternatively, if you're using SSL: | |||
|
|||
<script src="https://d1fxtkz8shb9d2.cloudfront.net/websocket-multiplex-0.1.js"> | |||
</script> | |||
|
|||
Usage example: | |||
|
|||
var sockjs_url = '/multiplex'; | |||
var sockjs = new SockJS(sockjs_url); | |||
|
|||
var multiplexer = new WebSocketMultiplex(sockjs); | |||
var ann = multiplexer.channel('ann'); | |||
var bob = multiplexer.channel('bob'); | |||
var carl = multiplexer.channel('carl'); | |||
|
|||
|
|||
Usage from the node.js server | |||
----------------------------- | |||
|
|||
On the node.js server side, you can use npm to get the code: | |||
|
|||
npm install websocket-multiplex | |||
|
|||
And a simplistic example: | |||
|
|||
var multiplex_server = require('websocket-multiplex'); | |||
|
|||
// 1. Setup SockJS server | |||
var service = sockjs.createServer(); | |||
|
|||
// 2. Setup multiplexing | |||
var multiplexer = new multiplex_server.MultiplexServer(service); | |||
|
|||
var ann = multiplexer.registerChannel('ann'); | |||
ann.on('connection', function(conn) { | |||
conn.write('Ann says hi!'); | |||
conn.on('data', function(data) { | |||
conn.write('Ann nods: ' + data); | |||
}); | |||
}); | |||
|
|||
// 3. Setup http server | |||
var server = http.createServer(); | |||
sockjs_echo.installHandlers(server, {prefix:'/multiplex'}); | |||
var app = express.createServer(); | |||
|
|||
For a full-featured example see the `/examples` directory. |
This file contains 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
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,3 @@ | |||
#!/usr/bin/env node | |||
var fs = require('fs') | |||
console.log(JSON.parse(fs.readFileSync('package.json')).version) |
This file contains 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
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,19 @@ | |||
WebSocket-multiplex SockJS example | |||
================================== | |||
|
|||
To run this example, first install dependencies: | |||
|
|||
npm install | |||
|
|||
And run a server: | |||
|
|||
node server.js | |||
|
|||
|
|||
That will spawn an http server at http://127.0.0.1:9999/ which will | |||
serve both html (served from the current directory) and also SockJS | |||
service (under the [/multiplex](http://127.0.0.1:9999/multiplex) | |||
path). | |||
|
|||
With that set up, WebSocket-multiplex is able to push three virtual | |||
connections over a single SockJS connection. See the code for details. |
This file contains 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
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,96 @@ | |||
<!doctype html> | |||
<html><head> | |||
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script> | |||
<script src="http://cdn.sockjs.org/sockjs-0.2.min.js"></script> | |||
<script src="http://cdn.sockjs.org/websocket-multiplex-0.1.js"></script> | |||
<style> | |||
.box { | |||
width: 300px; | |||
float: left; | |||
margin: 0 20px 0 20px; | |||
} | |||
.box div, .box input { | |||
border: 1px solid; | |||
-moz-border-radius: 4px; | |||
border-radius: 4px; | |||
width: 100%; | |||
padding: 0px; | |||
margin: 5px; | |||
} | |||
.box div { | |||
border-color: grey; | |||
height: 300px; | |||
overflow: auto; | |||
} | |||
.box input { | |||
height: 30px; | |||
} | |||
h1 { | |||
margin-left: 75px; | |||
} | |||
body { | |||
background-color: #F0F0F0; | |||
font-family: "Arial"; | |||
} | |||
</style> | |||
</head><body lang="en"> | |||
<h1>SockJS Multiplex example</h1> | |||
|
|||
<div id="first" class="box"> | |||
<div></div> | |||
<form><input autocomplete="off" value="Type here..."></input></form> | |||
</div> | |||
|
|||
<div id="second" class="box"> | |||
<div></div> | |||
<form><input autocomplete="off"></input></form> | |||
</div> | |||
|
|||
<div id="third" class="box"> | |||
<div></div> | |||
<form><input autocomplete="off"></input></form> | |||
</div> | |||
|
|||
<script> | |||
// Pipe - convenience wrapper to present data received from an | |||
// object supporting WebSocket API in an html element. And the other | |||
// direction: data typed into an input box shall be sent back. | |||
var pipe = function(ws, el_name) { | |||
var div = $(el_name + ' div'); | |||
var inp = $(el_name + ' input'); | |||
var form = $(el_name + ' form'); | |||
|
|||
var print = function(m, p) { | |||
p = (p === undefined) ? '' : JSON.stringify(p); | |||
div.append($("<code>").text(m + ' ' + p)); | |||
div.append($("<br>")); | |||
div.scrollTop(div.scrollTop() + 10000); | |||
}; | |||
|
|||
ws.onopen = function() {print('[*] open', ws.protocol);}; | |||
ws.onmessage = function(e) {print('[.] message', e.data);}; | |||
ws.onclose = function() {print('[*] close');}; | |||
|
|||
form.submit(function() { | |||
print('[ ] sending', inp.val()); | |||
ws.send(inp.val()); | |||
inp.val(''); | |||
return false; | |||
}); | |||
}; | |||
|
|||
var sockjs_url = '/multiplex'; | |||
var sockjs = new SockJS(sockjs_url); | |||
|
|||
var multiplexer = new WebSocketMultiplex(sockjs); | |||
var ann = multiplexer.channel('ann'); | |||
var bob = multiplexer.channel('bob'); | |||
var carl = multiplexer.channel('carl'); | |||
|
|||
pipe(ann, '#first'); | |||
pipe(bob, '#second'); | |||
pipe(carl, '#third'); | |||
|
|||
$('#first input').focus(); | |||
</script> | |||
</body></html> |
This file contains 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
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,9 @@ | |||
{ | |||
"name" : "websocket-multiplex-sockjs-example", | |||
"version" : "0.0.0-unreleasable", | |||
"dependencies" : { | |||
"express" : "2.5.8", | |||
"sockjs" : "0.2.x", | |||
"websocket-multiplex" : "*" | |||
} | |||
} |
This file contains 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
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,52 @@ | |||
var express = require('express'); | |||
var websocket_multiplex = require('websocket-multiplex'); | |||
|
|||
var sockjs = require('sockjs'); | |||
|
|||
|
|||
// 1. Setup SockJS server | |||
var sockjs_opts = {sockjs_url: "http://cdn.sockjs.org/sockjs-0.2.min.js"}; | |||
var service = sockjs.createServer(sockjs_opts); | |||
|
|||
|
|||
// 2. Setup multiplexing | |||
var multiplexer = new websocket_multiplex.MultiplexServer(service); | |||
|
|||
var ann = multiplexer.registerChannel('ann'); | |||
ann.on('connection', function(conn) { | |||
conn.write('Ann says hi!'); | |||
conn.on('data', function(data) { | |||
conn.write('Ann nods: ' + data); | |||
}); | |||
}); | |||
|
|||
var bob = multiplexer.registerChannel('bob'); | |||
bob.on('connection', function(conn) { | |||
conn.write('Bob doesn\'t agree.'); | |||
conn.on('data', function(data) { | |||
conn.write('Bob says no to: ' + data); | |||
}); | |||
}); | |||
|
|||
var carl = multiplexer.registerChannel('carl'); | |||
carl.on('connection', function(conn) { | |||
conn.write('Carl says goodbye!'); | |||
// Explicitly cancel connection | |||
conn.end(); | |||
}); | |||
|
|||
|
|||
// 3. Express server | |||
var app = express.createServer(); | |||
service.installHandlers(app, {prefix:'/multiplex'}); | |||
|
|||
console.log(' [*] Listening on 0.0.0.0:9999' ); | |||
app.listen(9999, '0.0.0.0'); | |||
|
|||
app.get('/', function (req, res) { | |||
res.sendfile(__dirname + '/index.html'); | |||
}); | |||
|
|||
app.get('/multiplex.js', function (req, res) { | |||
res.sendfile(__dirname + '/multiplex.js'); | |||
}); |
This file contains 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
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,86 @@ | |||
var WebSocketMultiplex = (function(){ | |||
|
|||
|
|||
// **** | |||
|
|||
var DumbEventTarget = function() { | |||
this._listeners = {}; | |||
}; | |||
DumbEventTarget.prototype._ensure = function(type) { | |||
if(!(type in this._listeners)) this._listeners[type] = []; | |||
}; | |||
DumbEventTarget.prototype.addEventListener = function(type, listener) { | |||
this._ensure(type); | |||
this._listeners[type].push(listener); | |||
}; | |||
DumbEventTarget.prototype.emit = function(type) { | |||
this._ensure(type); | |||
var args = Array.prototype.slice.call(arguments, 1); | |||
if(this['on' + type]) this['on' + type].apply(this, args); | |||
for(var i=0; i < this._listeners[type].length; i++) { | |||
this._listeners[type][i].apply(this, args); | |||
} | |||
}; | |||
|
|||
|
|||
// **** | |||
|
|||
var WebSocketMultiplex = function(ws) { | |||
var that = this; | |||
this.ws = ws; | |||
this.channels = {}; | |||
this.ws.addEventListener('message', function(e) { | |||
var t = e.data.split(','); | |||
var type = t.shift(), name = t.shift(), payload = t.join(); | |||
if(!(name in that.channels)) { | |||
return; | |||
} | |||
var sub = that.channels[name]; | |||
|
|||
switch(type) { | |||
case 'uns': | |||
delete that.channels[name]; | |||
sub.emit('close', {}); | |||
break; | |||
case 'msg': | |||
sub.emit('message', {data: payload}); | |||
break; | |||
} | |||
}); | |||
}; | |||
WebSocketMultiplex.prototype.channel = function(raw_name) { | |||
return this.channels[escape(raw_name)] = | |||
new Channel(this.ws, escape(raw_name), this.channels); | |||
}; | |||
|
|||
|
|||
var Channel = function(ws, name, channels) { | |||
DumbEventTarget.call(this); | |||
var that = this; | |||
this.ws = ws; | |||
this.name = name; | |||
this.channels = channels; | |||
var onopen = function() { | |||
that.ws.send('sub,' + that.name); | |||
that.emit('open'); | |||
}; | |||
if(ws.readyState > 0) { | |||
setTimeout(onopen, 0); | |||
} else { | |||
this.ws.addEventListener('open', onopen); | |||
} | |||
}; | |||
Channel.prototype = new DumbEventTarget() | |||
|
|||
Channel.prototype.send = function(data) { | |||
this.ws.send('msg,' + this.name + ',' + data); | |||
}; | |||
Channel.prototype.close = function() { | |||
var that = this; | |||
this.ws.send('uns,' + this.name); | |||
delete this.channels[this.name]; | |||
setTimeout(function(){that.emit('close', {});},0); | |||
}; | |||
|
|||
return WebSocketMultiplex; | |||
})(); |
Oops, something went wrong.