Evan Zamir
Evan Zamir

Reputation: 8431

How to setup RabbitMQ binding for browser clients?

I'm using socket.io to stream data messages from RabbitMQ to the browser, but so far I've only figured out how to hard code the server to subscribe to a single (pre-specified) routing key (in the code below it is message.1). What I would like to do is create an api so that each client (browser session) can subscribe to whatever routing keys they would like, and have socket.io stream only the subscribed messages to those clients. Here is the code I already have:

//app.js    
var express = require('express'),
        routes = require('./routes'),
        api = require('./routes/api'),
        http = require('http'),
        path = require('path');


var amqp = require('amqp'),
    rabbitMq = amqp.createConnection({ url: "amqp://guest:guest@localhost" },
        {defaultExchangeName: "amq.topic"});

var app = module.exports = express(),
    server = http.createServer(app),
    io = require('socket.io').listen(server);


/**
 * Configuration
 */

// all environments
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.static(path.join(__dirname, 'public')));
app.use(app.router);

// development only
if (app.get('env') === 'development') {
  app.use(express.errorHandler());
}

// production only
if (app.get('env') === 'production') {
  // TODO
};


/**
 * Routes
 */

// serve index and view partials
app.get('/', routes.index);
app.get('/partials/:name', routes.partials);

// JSON API
app.get('/api/name', api.name);

// redirect all others to the index (HTML5 history)
app.get('*', routes.index);


rabbitMq.on('ready', function () {
    io.sockets.on('connection', function (socket) {
        var exchange = rabbitMq.exchange('my-exchange',{durable:true});
        var queue = rabbitMq.queue('my-queue',{durable: true});

        queue.bind(exchange,'message.1'); // all messages

        queue.subscribe(function (message) {
            socket.broadcast.emit('message', {
                msg: decodeURIComponent(message.data),
                ts: Date()
            });
            console.log(message);
        });
    });
});


/**
 * Start Server
 */

server.listen(app.get('port'),function() {
    console.log("Express server listening on port " + app.get('port'));
});

I tried taking the rabbitMQ code out of app.js and placing it into api.js, but that didn't seem to work. Any advice or guidance about the next step here would be appreciated. I've been scouring the web and SO for relevant examples/tutorials, but can't seem to find any suitable ones.

Upvotes: 2

Views: 4911

Answers (2)

1ManStartup
1ManStartup

Reputation: 3816

This is an example that explains how to do it in NodeJS with Express, node-AMQP, and SocketIO:

  https://github.com/jamescarr/nodejs-amqp-example/blob/master/node/app.js

As old_sound posted above, you use socket.send from your serverside app.js file, doing this allows you to send the value to the client side from within socket io.

Although I would recommend using sock.js for scalability.

Upvotes: 0

old_sound
old_sound

Reputation: 2313

You need to implement a way to send a message from the browser with the specific routing key that you want the client to get messages from.

Once you get that routing key, use it in the queue.bind instead of message.1

Upvotes: 0

Related Questions