Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add sub topic feature on registered channels. #15

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,6 @@
examples/sockjs/node_modules


.idea/

node_modules/
30 changes: 25 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,11 @@ 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>
<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>
<script src="https://d1fxtkz8shb9d2.cloudfront.net/websocket-multiplex-0.1.js"></script>

Usage example:

Expand All @@ -35,6 +33,18 @@ Usage example:
var carl = multiplexer.channel('carl');
```

If the sub topic is activated on server configuration, you have the possibility to create one with dot separated syntax.

```javascript
var sockjs_url = '/multiplex';
var sockjs = new SockJS(sockjs_url);

var multiplexer = new WebSocketMultiplex(sockjs);
var ann = multiplexer.channel('ann.spell');
var bob = multiplexer.channel('bob.age');
var carl = multiplexer.channel('carl.23');
```

Usage from the node.js server
-----------------------------

Expand Down Expand Up @@ -67,11 +77,21 @@ And a simplistic example:
var app = express.createServer();
```

To authorize sub topic, it is necessary to add the configuration of the option during creation of MultiplexServer.
This configuration is deactivated by default.

```javascript

// Setup multiplexing with sub topic
var opts = {allowSubTopic: true};
var multiplexer = new multiplex_server.MultiplexServer(service, opts);

```

For a full-featured example see the
[/examples/sockjs](https://github.com/sockjs/websocket-multiplex/tree/master/examples/sockjs)
directory.


Protocol
--------

Expand Down
48 changes: 48 additions & 0 deletions examples/sockjs-subtopic/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<!DOCTYPE html>
<html>

<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>SockJS - Sub topic multiplex sample</title>

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap-theme.min.css">

<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
</head>

<body ng-app="subTopicSample">

<div class="container" ng-controller="MainCtrl">
<div class="row">
<div class="col-md-6">
<cjs-line dataset="lineData" responsive="true"></cjs-line>
</div>
<div class="col-md-6">
<p ng-repeat="message in bMessages track by $index">{{message}}</p>
</div>
</div>
</div>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>

<script src="http://cdn.sockjs.org/sockjs-0.3.min.js"></script>
<script src="http://cdn.sockjs.org/websocket-multiplex-0.1.js"></script>

<script src="js/random.min.js"></script>
<script src="js/Chart.min.js"></script>

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.11/angular.min.js"></script>

<script src="js/angular-chartjs.min.js"></script>
<script src="js/app.js"></script>
</body>
</html>
11 changes: 11 additions & 0 deletions examples/sockjs-subtopic/js/Chart.min.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions examples/sockjs-subtopic/js/angular-chartjs.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

50 changes: 50 additions & 0 deletions examples/sockjs-subtopic/js/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
var sockjs = new SockJS('/multiplex');
var multiplexer = new WebSocketMultiplex(sockjs);

var random = new Random();
var aChannel = multiplexer.channel('a.' + random.integer(1, 20));
var bChannel = multiplexer.channel('b.' + random.integer(1, 20));

var app = angular.module('subTopicSample', ['chartjs']);

app.controller('MainCtrl', function($scope) {

$scope.lineData = {
labels: ["Paris", "New York", "London", "Berlin"],
datasets: [{
fillColor: "rgba(220,220,220,0.5)",
strokeColor: "rgba(220,220,220,1)",
pointColor: "rgba(220,220,220,1)",
pointStrokeColor: "#fff",
data: [10, 20, 5, 35]
}]
};
$scope.bMessages = [];

aChannel.onmessage = function(e) {
var obj = JSON.parse(e.data);
$scope.lineData = {
labels: ["Paris", "New York", "London", "Berlin"],
datasets: [{
fillColor: "rgba(220,220,220,0.5)",
strokeColor: "rgba(220,220,220,1)",
pointColor: "rgba(220,220,220,1)",
pointStrokeColor: "#fff",
data: [obj.paris, obj.newYork, obj.london, obj.berlin]
}]
};
$scope.$apply();
};

bChannel.onmessage = function(e) {
var obj = JSON.parse(e.data);
$scope.bMessages.push("Nb de contacts : " + obj.value);

if ($scope.bMessages.length > 15) {
bMessage.pop();
}

$scope.$apply();
};
}
);
1 change: 1 addition & 0 deletions examples/sockjs-subtopic/js/random.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions examples/sockjs-subtopic/log4js.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"appenders": [
{
"type": "console"
}
],
"replaceConsole": true
}
11 changes: 11 additions & 0 deletions examples/sockjs-subtopic/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"name" : "websocket-multiplex-sockjs-subtopic-example",
"version" : "0.0.0-unreleasable",
"dependencies" : {
"express" : "3.0.0",
"log4js" : "0.6.20",
"sockjs" : "0.3.x",
"random-js" : "1.0.4",
"websocket-multiplex" : "git://github.com/gdepuille/websocket-multiplex.git#feature/subTopic"
}
}
129 changes: 129 additions & 0 deletions examples/sockjs-subtopic/server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
/**
* Server sample to allow sub topic on multiplexed SockJS
*
* @author GregoryDepuille
*/

var _ = require('underscore-node');
var http = require('http');
var express = require('express');
var sockjs = require('sockjs');
var multiplex_server = require('websocket-multiplex');
var log4js = require('log4js');
var random = require("random-js")();

log4js.configure('log4js.json');
var logger = log4js.getLogger("sub-topic-sample");

// Registered connection by topic
var aSockets = [];
var bSockets = [];

function makeChannel(sockJsMux, channelName) {
logger.info("Add channel " + channelName);
return sockJsMux.registerChannel(channelName);
}

function filterTopicPredicate(topicSocket) {
return this === topicSocket.conn;
}

function cleanTopic(connection, arrays) {
var f = _.filter(arrays, filterTopicPredicate, connection);
for (var i = 0 ; i < f.length ; i++) {
var idx = arrays.indexOf(f[i]);
arrays.splice(idx, 1);
}
}

function configureMasterEvents(sockJsServer) {
sockJsServer.on('connection', function (socket) {
logger.info("Main socket opened " + socket);

// Manage closed connection from browser
socket.on('close', function () {
logger.info("Main socket closed " + socket);

// Remove sockets.
cleanTopic(socket, aSockets);
cleanTopic(socket, bSockets);
});
});
}

function configureChannelEvents(channel, arrays) {
channel.on('connection', function (socket) {
logger.info("Opened connection to " + socket.topic + " " + socket.conn);
arrays.push(socket);
});
}

function notifyA(subTopic) {
for (var i = 0 ; i < aSockets.length ; i++) {
var socket = aSockets[i];
if (socket.topic === "a." + subTopic) {
var message = {
paris: random.integer(1, 200),
newYork: random.integer(1, 200),
london: random.integer(1, 200),
berlin: random.integer(1, 200)
};

socket.write(JSON.stringify(message));
logger.info("Send a message on a." + subTopic + " channel to " + socket.conn);
}
}
}


function notifyB(subTopic) {
for (var i = 0 ; i < bSockets.length ; i++) {
var socket = bSockets[i];
if (socket.topic === "b." + subTopic) {
socket.write(JSON.stringify({ value: random.integer(1, 20) }));
logger.info("Send a message on b." + subTopic + " channel to " + socket.conn);
}
}
}


logger.info('Init sample')
var sockJsServer = sockjs.createServer();
var sockJsMux = new multiplex_server.MultiplexServer(sockJsServer, {allowSubTopic: true});

configureMasterEvents(sockJsServer);
configureChannelEvents(makeChannel(sockJsMux, 'a'), aSockets);
configureChannelEvents(makeChannel(sockJsMux, 'b'), bSockets);

var app = express();
var httpServer = http.createServer(app);
sockJsServer.installHandlers(httpServer, {prefix:'/multiplex'});
httpServer.listen(9999, '0.0.0.0');

app.get('/', function (req, res) {
res.sendfile(__dirname + '/index.html');
});

app.get('/js/app.js', function (req, res) {
res.sendfile(__dirname + '/js/app.js');
});

app.get('/js/Chart.min.js', function (req, res) {
res.sendfile(__dirname + '/js/Chart.min.js');
});

app.get('/js/angular-chartjs.min.js', function (req, res) {
res.sendfile(__dirname + '/js/angular-chartjs.min.js');
});

app.get('/js/random.min.js', function (req, res) {
res.sendfile(__dirname + '/js/random.min.js');
});

setInterval(function () {
var a = random.integer(1, 20);
notifyA(a);

var b = random.integer(1, 20);
notifyB(b);
}, 500);
4 changes: 4 additions & 0 deletions multiplex_client.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,3 +84,7 @@ var WebSocketMultiplex = (function(){

return WebSocketMultiplex;
})();

if (typeof exports === 'object' && typeof module === 'object') {
module.exports = WebSocketMultiplex;
}
Loading