Как настроить привязку RabbitMQ для клиентов браузера?

Я использую socket.io для потоковой передачи сообщений данных из RabbitMQ в браузер, но до сих пор я только понял, как жестко запрограммировать сервер для подписки на один (заранее указанный) ключ маршрутизации (в коде ниже это message.1). Что я хотел бы сделать, так это создать API, чтобы каждый клиент (сеанс браузера) мог подписаться на любые ключи маршрутизации, которые они хотели бы, и чтобы socket.io передавал только подписанные сообщения этим клиентам. Вот код, который у меня уже есть:

//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'));
});

Я попытался взять код rabbitMQ из app.js и поместить его в api.js, но это, похоже, не сработало. Любые советы или рекомендации относительно следующего шага здесь будут оценены по достоинству. Я искал в Интернете и SO соответствующие примеры/учебники, но, похоже, не нашел подходящих.


person Evan Zamir    schedule 02.09.2013    source источник


Ответы (2)


Вам нужно реализовать способ отправки сообщения из браузера с определенным ключом маршрутизации, от которого вы хотите, чтобы клиент получал сообщения.

Как только вы получите этот ключ маршрутизации, используйте его в queue.bind вместо message.1

person old_sound    schedule 02.09.2013
comment
Правильно, как это сделать? Вот что я спрашиваю. - person Evan Zamir; 02.09.2013
comment
Прочитайте документы о socket.send(); с клиента и socket.onmessage() с сервера. Это на пути к этому. Другой будет использовать параметры GET/POST. Это зависит от того, что лучше подходит для вашей проблемы - person old_sound; 03.09.2013
comment
Я хочу сделать это с помощью REST, но до сих пор не понял, как это сделать. - person Evan Zamir; 05.09.2013

Это пример, который объясняет, как это сделать в NodeJS с помощью Express, node-AMQP и SocketIO:

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

Как указано выше old_sound, вы используете socket.send из файла app.js на стороне сервера, что позволяет отправлять значение на сторону клиента из сокета io.

Хотя я бы рекомендовал использовать sock.js для масштабируемости.

person 1ManStartup    schedule 14.09.2013