繁体   English   中英

node.js + socket.io + redis + rails - 实时应用程序

[英]node.js + socket.io + redis + rails — RealTime application

我需要在我的应用程序(Ruby On Rails)中添加实时,所以,我认为更好的方法是使用node.js + socket.io + redis。

我在后端有这个application.js文件(node.js)

var app = require('http').createServer();
var io = require('socket.io');
var redis = require('redis').createClient();
var _ = require('underscore')._;

io = io.listen(app);
io.configure(function() {
    io.set("transports", ["xhr-polling"]);
    io.set("polling duration", 10);
    io.set("close timeout", 10);
    io.set("log level", 1);
})

redis.subscribe('rt-change');

io.on('connection', function(socket) {
    redis.on('message', function(channel, message) {
        socket.emit('rt-change', message)
    });
});

var port = process.env.PORT || 5001;
app.listen(port);

和前端的messages.js

 var socket = io.connect('http://localhost:5001/socket.io');
socket.on('rt-change', function (data) {
    console.log(data);
});

我正在使用node application.js命令启动application.js,它可以工作!

MacBook-Pro-Zhirayr:rt zhirayr $ node application.js info - socket.io启动

但是当我尝试从Rails应用程序发送带有redis的消息($ redis.publish'rt-change',{hello:'world'})时,我的浏览器不会在控制台中记录任何内容。 我确定,从浏览器建立的连接,导致我停止节点时,它会抛出连接拒绝错误。 我确信redis和node之间的连接已建立,导致application.js中的console.log(message)记录它。 但是浏览器中的console.log不会记录任何内容。

有什么想法吗?

谢谢。

UPD for #Antoine

在application.js中添加了console.log io.on('connection',function(socket){redis.on('message',function(channel,message){console.log('redis'的新消息); socket。发出('rt-change',message);});});

当r.publish'rt-change',{:hello =>'world'}被执行时,节点记录下:

new message from redis
new message from redis
new message from redis
new message from redis
new message from redis
new message from redis
new message from redis
new message from redis
new message from redis
new message from redis
new message from redis

奇怪的是,1个消息的节点记录11次。

 var socket = io.connect('http://localhost:5001/socket.io');
socket.on('rt-change', function (data) {
    console.log(data);
});

这部分代码似乎不正确,根据http://socket.io上的文档,您应该执行以下操作:

<script src="http://localhost:5001/socket.io/socket.io.js"></script>
<script>
  var socket = io.connect('http://localhost:5001');
</script>

您为单个发布获得多次执行的原因是您的代码中嵌套的事件处理。 我会尽力解释这个问题。

你打电话的时候

io.on('connection', function(socket) {...});

你监听connection事件并将给定的函数添加为事件处理程序。 只要新用户连接,就会执行它。 这为每次执行处理程序创建了一个单独的作用域。

当你打电话给这个

io.on('connection', function(socket) {
    redis.on('message', function(channel, message) {
        console.log('new message from redis');
        socket.emit('rt-change', message);
    });
});

您为每个连接的用户分别添加redis订阅者事件message侦听器。 这就是您获取多个日志和连接用户获得相同邮件的多个副本的原因。 您有11条消息,这意味着当时有11个不同的用户连接。

为了解决这个问题,你可以调用once ,而不是on听事件。 像这样

io.once('connection', function(socket) {
    redis.on('message', function(channel, message) {
        console.log('new message from redis');
        socket.emit('rt-change', message);
    });
});

这也适用于socket.io客户端。 请参阅我以前的答案,以明确这一点:

  1. socket.io代码结构:放置方法的位置?
  2. socket.io在重新连接后再创建一个连接

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM