簡體   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