我在NodeJS + Redis + PHP中构建一个发布/订阅服务器,在深入研究主题并开始构建某些东西之后,我遇到了一些我在这个过程中看到的混乱。
示例场景:
NodeJs
正确连接到套接字。 alert
设置视图:
<input type="text" id="message">
<button id="sendMessage">Send alert</button>
客户端Js
var socket = io.connect('http://127.0.0.1:3000/');
socket.on('notification', function (data) {
alert(data.message);
console.log('message received');
});
// Ajax event
$(document).on('click','#sendMessage', function(){
$.ajax({
url: '/send/notification',
method: 'POST',
type: 'JSON',
data: { message: $('#message').val() },
success:function(data)
{
console.log('message sent');
}
})
});
用于与redis通信的Php服务器端
$message = $_POST['message'];
$redis = new Predis\Client();
$redis->publish('notification',$message);
的NodeJS
此时我的NodeJs
服务器上的我将在redis中收听消息事件,然后将事件广播到套接字,但这是我遇到的第一个问题。
var http = require('http');
var app = http.createServer();
var io = require('socket.io')(app);
var redis = require('redis');
app.listen(3000,'127.0.0.1',function(){
console.log("listening:", app.address().port, app.address().address);
});
io.on('connection', function(client){
var redisClient = redis.createClient();
redisClient.subscribe('notification');
redisClient.on("message",function(channel,data){
// This line should broadcast to all the client except the sender
socket.broadcast.emit(channel,JSON.parse(data));
console.log(channel);
});
});
此时我console.log()
我可以在我的终端5日志上看到channel
&#34;通知&#34;为什么5?
当socket.io broadcast
事件时,它执行 5次,在这种情况下发送 5 alert()
到{{1并且 4 到clients
而不是1为所有客户端为0为发件人。
时间取决于连接的用户数量我真的不明白我错过了什么,因为它不应该是正确的行为。
我已经尝试将sender
的创建和redisClient
之外的频道订阅设置为没有运气,同样的结果。
另一项测试
如果我io.on('connection')
套接字连接上的事件如下:
broadcast
它正常工作,所以我认为是redis问题。任何建议都会非常感激。
答案 0 :(得分:2)
您连接了5个客户端,因此“连接”事件被触发5次。 因此,有5个redis听众,然后播放。
有两种方法可以正确完成:
a)每个连接1个监听器,仅将消息发送到连接
io.on('connection', function(socket){
var redisClient = redis.createClient();
redisClient.subscribe('notification');
redisClient.on("message",function(channel,data){
// This line should broadcast to only the current connection
socket.emit(channel,JSON.parse(data));
console.log(channel);
});
});
b)1个全局监听器,向所有客户端广播
var redisClient = redis.createClient();
redisClient.subscribe('notification');
redisClient.on("message",function(channel,data){
// This line should broadcast to all the client except the sender
io.sockets.emit(channel,JSON.parse(data));
console.log(channel);
});
我更喜欢方法b)因为它只需要一个redis连接。
答案 1 :(得分:-1)
我在一个项目中做了同样的事情。唯一不同的是我从node.js发布通知但我没有得到任何问题。有广播只有开放套接字。