Dynamic room almost successful except for conn.on('data' that doubles up on old rooms for every new room created

90 views
Skip to first unread message

julienp...@gmail.com

unread,
Mar 5, 2014, 8:22:23 PM3/5/14
to soc...@googlegroups.com
Hey,
After much effort, I finally have some code to implement a dynamic chat room using the websocket-multiplex plug in with sockjs and node (First, we activate the new room by going to /activate then we can connect the new mutliplexed websocket).
I simply replaced the static ann/bob example with an array of multiplexers (I tried to understand the example given on https://github.com/sockjs/websocket-multiplex/blob/master/multiplex_server.js but i don't understand how it adapts to the ann, bob example)
Everything works swimmingly for the first connexion. The user comes in and when they send some data to the websocket server, it console logs it.

data received: data1
data received: data2
data received: data3

Then when the second connexion comes in, suddenly the first conn.on('data' gets added to the second one and the code for that event gets executed twice for both chat rooms.

data received: data1
data received: data1
data received: data2
data received: data2
data received: data3
data received: data3

It is all duped

How can I correct this?

var express = require('express');
var sockjs  = require('sockjs');
var http    = require('http');
var multiplex_server = require('websocket-multiplex');



var howManyOpenConns = [];
var sockJsConn = [];

// Sockjs server
var sockjs_opts = {sockjs_url: "http://cdn.sockjs.org/sockjs-0.3.min.js"};
var sockjs_chat = sockjs.createServer(sockjs_opts);
var multiplexer = new multiplex_server.MultiplexServer(sockjs_chat);



// Express server
var app = express();
var server = http.createServer(app);

sockjs_chat.installHandlers(server, {prefix:'/chat'});

console.log(' [*] Listening on 0.0.0.0:8880' );
server.listen(8880,'0.0.0.0');


app.get('/activate', function(req, res) {
        console.log('Somebody is trying to activate: ' + req.query.id);
	if (isNaN(howManyOpenConns[req.query.id])) {howManyOpenConns[req.query.id]=0;};
	console.log('There are currently ' + howManyOpenConns[req.query.id] + ' connections on that object');
	if (howManyOpenConns[req.query.id]<1) {
		console.log('Open a new redis client');
		sockJsConn[req.query.id] = multiplexer.registerChannel('' + req.query.id);
		// BEGIN socket connection procedures 
            	sockJsConn[req.query.id].on('connection', function(conn) {
			howManyOpenConns[req.query.id] = howManyOpenConns[req.query.id] + 1;
			console.log('Increased number of connections for ' + req.query.id + ' to ' + howManyOpenConns[req.query.id]);
		console.log('Testing for OpenConns: ' + howManyOpenConns[req.query.id]);
		if (howManyOpenConns[req.query.id]<2) {
		console.log('This is the first time the socket multiplex opens, let s setup its redis, on data and on close rules');
               	conn.write('Welcome to sockjs Channel' + req.query.id );
		conn.on('data', function(data) {
			console.log('data received: ' + data);
			// BUG BUG BUG: This event applies to ALL conns for all multiplexed connections while I want it to be dedicated to the one connection!!!
		});
		conn.on('close', function() {
			console.log('closed' + req.query.id);
 			howManyOpenConns[req.query.id] = howManyOpenConns[req.query.id] -1;
			console.log('total connections left: ' + howManyOpenConns[req.query.id]);
					    });
		// END procedures when sockjs connection is closed
					}
									         });
		// END OF on socket connection procedures
		// BEGIN on socket receives data procedures
                //sockJsConn[req.query.id].on('data', function(data) {console.log('does not work');});
					       }
	else {
		console.log('I already know you!');
	     }
        res.send('You successfully activated sockJsConn ' + req.query.id);
});

//setInterval(function() {
//},3000);

// new stuff


// eo new stuff

Chris-S

unread,
Mar 11, 2014, 7:57:04 PM3/11/14
to soc...@googlegroups.com
With a brief read, after multiplexing you'll never want to: conn.write()

conn.on open and close should be outside the main loop as events.

As your now dealing in the multiplexed state in your main loop, change conn.write(..); to sockJsConn[req.query.id].write(..);

Chris-S

Chris-S

unread,
Mar 11, 2014, 8:17:14 PM3/11/14
to soc...@googlegroups.com
and conn.on('data'.. should be sockJsConn[req.query.id].on('data'..

On Thursday, 6 March 2014 14:22:23 UTC+13, Julien Jacquet wrote:

Omair...@pixel8ltd.com

unread,
Mar 21, 2014, 12:49:11 PM3/21/14
to soc...@googlegroups.com
Hi Julien,

Did you get anywhere with your issue - as i'm having the same issue where 

conn.on('data', function(data) {
   console.log('data received: ' + data);
   // BUG BUG BUG: This event applies to ALL conns for all multiplexed connections while I want it to be dedicated to the one connection!!!
 });

Thanks.

Chris-S

unread,
Mar 25, 2014, 6:16:08 AM3/25/14
to soc...@googlegroups.com, Omair...@pixel8ltd.com
Did you try referencing the one connection?

change:
conn.on('data', function(data) {

to:
sockJsConn[req.query.id].on('data', function(data) {


Omair...@pixel8ltd.com

unread,
Mar 25, 2014, 7:12:10 AM3/25/14
to soc...@googlegroups.com, Omair...@pixel8ltd.com
Yes tried that but that wouldn't work because inside a sockJsConn[req.query.id.on(connection, function(conn) you are passed the conn which you have to use.

I did however fix the issue --- the problem was in websocket-multiplex library and how it was using the stream module (i'm not sure the reasoning behind it).  I forked it and fixed it for my use case and now it does work how i thought it should be working:

Julien Jacquet

unread,
Mar 26, 2014, 12:33:03 AM3/26/14
to soc...@googlegroups.com, Omair...@pixel8ltd.com
Hey guys,
So there is a complete solution for this here:
Reply all
Reply to author
Forward
0 new messages