【发布时间】:2014-12-08 14:51:56
【问题描述】:
我正在用 NodeJS + Redis + PHP 构建一个 Pub/Sub 服务器,在深入研究了这个主题并开始构建一些东西之后,我在这个过程中遇到了一些困惑。
示例场景:
-
5 个用户通过
NodeJs正确连接到套接字。 - 其中一个人单击按钮将自定义
alert发送给除他之外的所有连接用户 - Php 通过调用 ajax 接收警报消息(作为示例)
- PHP 发布回 Redis
- Redis 接收事件并触发 socket.io 广播事件
设置视图:
<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 中侦听 message 事件,然后将事件广播到套接字,但这是我遇到的第一个问题。
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()channel在我的终端上可以看到5个日志“通知”为什么是5个?
当 socket.io broadcast 事件发生时,它会执行 5 次,在这种情况下发送 5 alert() 到 clients 和 4 到sender,而不是所有客户端的 1 和发件人的 0。
时间取决于连接的用户数量我真的不明白我错过了什么,因为这不应该是正确的行为。
我已经尝试将redisClient 的创建和频道订阅放在io.on('connection') 之外,但没有成功,结果相同。
另一个测试
如果我broadcast 套接字连接上的事件是这样的:
io.on('connection', function(client)
{
client.broadcast.emit('notification','hello');
});
它工作正常,所以我认为是redis问题。任何建议将不胜感激。
【问题讨论】:
-
有点离题,但我不太清楚你为什么使用 PHP。您可以只调用 NodeJS WebService 来发布消息,并且您将摆脱开发堆栈的另一部分(除非您不需要 PHP 来处理其他事情)...
标签: node.js sockets redis socket.io node-redis