senty
senty

Reputation: 12857

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

I want to make a notifications system based on events triggered by a user and gets delivered to another user ('X wrote on your wall). I understand the logic of broadcasting event, but if I broadcast, the message will be sent to everyone on the channel.

I am using Laravel 5 and I used Jeffrey Way's Nodejs, Redis, Socket.io tutorial. Very helpful.

For broadcasting and catching the messages,


Until here everything is clear however at this point I got lost. I have couple of questions.

Edit: I found this SO answer, and I believe it solves my problem, but I couldn't adapt it on redis instance.

Upvotes: 4

Views: 4232

Answers (1)

Dave Thomas
Dave Thomas

Reputation: 3837

Alright here it is as per #2 in my comment above. Forgive me for not including Redis into the mix here.

Your server probably has some sort of authentication login endpoint. I'm going to use json web token in this example. You may use something else. But you will need a way identify your users in your socket connections. https://auth0.com/blog/2014/01/15/auth-with-socket-io/

A client authenticates in some way perhaps a RESTful API call and gets a json web token:

//Server

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

Then they connect to your socket.io server passing that token in the query as ?token="fasfsadfsaf"

//Client

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

On your sever you handle decoding the token into a user

//Server

//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);
});

The user can now be reached by broadcasting to that room

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

For your other questions:

  • Cluster will help you scale across multiple processes/servers. Redis helps with this as well. Add this when you got the basic frame down.

  • If your users are reconnecting at every page perhaps the pages should be loaded with ajax? You don't have to worry about different socket ids if you are identifying the users by some sort of authentication method rather than by the socket id.

Sorry if this answer isn't a complete answer, I'm new to this stuff too as well. But hopefully this is some direction that you can work with. Just helping some more since I started off in the comments.

Upvotes: 7

Related Questions