事件广播到特定用户(套接字).Io, redis, node)

Event Broadcasting to a Specific User (socket.io, redis, node)

本文关键字:Io redis node 套接字 广播 用户 事件      更新时间:2023-09-26

我想创建一个基于用户触发事件的通知系统,并将其传递给另一个用户('X写在你的墙上')。我理解广播事件的逻辑,但是如果我广播,消息将被发送给频道上的每个人。

我正在使用Laravel 5,我使用Jeffrey Way的Nodejs, Redis, Socket。io教程。很有帮助。

对于广播和捕获消息,

  • Server.js

    var server = require('http').Server();
    var io = require('socket.io')(server);
    var Redis = require('ioredis');
    var redis = new Redis();
    redis.subscribe('globalNotificationChannel');
    redis.on('message', function(channel, message) {
        message = JSON.parse(message);
        io.emit(channel + ':' + message.event, message.data);
    });
    server.listen(3000);
    
      客户
    • <script>
         var socket = io('http://localhost:3000');
         socket.on('globalNotificationChannel:WroteOnWall', function(data) {
              //     (Notification Received)
             //      console.log(data.message)
           }.bind(this));
         }
      <script>
      
    • 触发行动

      $data = [
        'event' => 'WroteOnWall',
        'data' => [
            'message' => $username + ' wrote on your wall.'
        ]
      ];
      Redis::publish('globalNotificationChannel', json_encode($data));
      


直到这里一切都很清楚,但在这一点上我迷路了。我有几个问题。

  • 首先,如果每个人都订阅了同一频道,我如何将触发的事件传递到特定用户的频道。

  • 或者有一种方法可以制作独特的通道?如果是这样,我如何存储unique_channel_ids以防止任何错误?

  • 其次,我看到人们正在使用集群。这对我的案子有用吗?它会给我带来什么好处吗?

  • 请注意,在客户端,我将其插入母版页,因为我需要在每个页面中运行,但是现在,我需要在每个页面中调用"连接"answers"侦听"。当重新运行连接脚本时,我不会得到不同的套接字吗?

编辑:我找到了这个答案,我相信它解决了我的问题,但我不能适应它在redis实例

好了,这里是按照我上面评论的#2。请原谅我在这里没有包括Redis。

您的服务器可能有某种身份验证登录端点。在这个例子中,我将使用json web token。你可以用别的东西。但是您需要一种在套接字连接中识别用户的方法。https://auth0.com/blog/2014/01/15/auth-with-socket-io/

客户端以某种方式(可能是RESTful API调用)进行身份验证并获得json web令牌:

//服务器

var jwt = require('jsonwebtoken');
var returnedToken = jwt.sign(user, app.get('superSecret'), {
            expiresInMinutes: 1440 // expires in 24 hours
        });

然后它们连接到您的插座。IO服务器在查询中传递该令牌为?token="fasfsadfsaf"

//客户端

var socket = io('http://localhost:3000', { query: 'token='+token });

在您的服务器上处理将令牌解码为用户

//服务器

//This adds the jwt session token to handshake when connecting to the socket
var socketioJwt = require('socketio-jwt');
io.use(socketioJwt.authorize({
    secret:'superSecret',
    handshake:true
}));
//When a user connects throw them in their own unique room
io.on('connection', function (socket) {
    //This will get the encoded user object in the JWT token
    var user = socket.decoded_token;
    //This puts them into their unique room
    socket.join('user_room_'+user._id);
});

用户现在可以通过广播到达那个房间

io.to('user_room_'+referenceToSameUserId).emit('Your message');

其他问题:

  • 集群将帮助您跨多个进程/服务器进行扩展。Redis在这方面也有帮助。当你完成基本框架后添加这个

  • 如果你的用户在每个页面都重新连接,也许页面应该用ajax加载?如果您通过某种身份验证方法而不是套接字id来标识用户,则不必担心不同的套接字id。

抱歉,如果这个答案不是一个完整的答案,我对这个东西也很陌生。但希望这是你们能理解的方向。我只是想帮助大家,因为我开始在评论