0

I've got a question about scaling a SailJS app on Heroku.

The setup :

  • SailJS
  • Kue (Redis queueing system)
  • Connected clients by means of socket io (sailsjs)
  • 2 dyno's (each run a SailsJS instance)
  • CronJob kind of process

I want to autonomously run a continuous 'cron' process, which triggers a push message, which must be sent to a connected socketio client. I am aware the socket connections reside in Redis, when this is configured correctly.

I use kue for nodejs, and trigger a worker to process the task. The worker is situated in the SailsJS instance, to be able to send a connected socket client a push message.

But I wonder, not every SailsJS instance (dyno) has the same connected sockets right? In other words, does every SailsJS instance has the same connected socket clients available, or is it possible dyno1 has a set of connected clients, and the other dyno the other set of clients??

e.g:

Heroku Cloud => Cron                      => Kue (Redis)
             => Dyno 1 (SailsJS instance) => client 1
                                          => client 2
             => Dyno 2 (SailsJS instance) => client 3
                                          => client 4

How does one solve this... :-D?

kaasdude
  • 1,336
  • 2
  • 8
  • 13

2 Answers2

0

To give a lead to a potential answer:

Seems the guys at sails.js are working on this now! See: https://github.com/balderdashy/sails/issues/2593

I hope these guys wil enable the 'subscribers()' method in behaving in same fashion as e.g. 'message()' does.

In my opinion when the method: 'message()' enables you the send a message to client connected to another sails instance, the method 'subscribers()' should return subscribers (socket id's) connected to both sails instances or it should be really nice to have to know if a instance is able to know if a specific client is connected.

Thanks!

kaasdude
  • 1,336
  • 2
  • 8
  • 13
0

What I do is to subscribe a socket to its own room (usually the room is the user Id). This way, you don't need to track the socket id (which changes for every browser connection). When any part of my app needs to "talk" to a connection, it emits a message to the room. This is good because it allows a user with multiple devices to receive the same message (just like when you have Skype on your desktop and on your phone, and you can chat using any of them interchangeably).

So, user A connects with the desktop, I subscribe his/her socket 1235 to his/her room UserA. If user A connects at the same time with a phone, I subscribe socket 4567 to room UserA. If any worker needs to send a message, it emits to room UserA. You can use socket.io-emitter: https://github.com/socketio/socket.io-emitter

var io = require('socket.io-emitter')({ "host" : REDIS_WEBSOCKET_HOST, "port" : REDIS_WEBSOCKET_PORT });

io.in("userA").emit("message", "Some message");

EDIT

Also, remember Sails has a broadcast feature:

http://sailsjs.org/documentation/reference/web-sockets/sails-sockets/sails-sockets-broadcast

You can send a message to a room. If your message is global, you can have all your sockets subscribe to a global room and any Sails instance will be able to communicate with everyone. If you still want to track individual sockets, you can still use my technique above and use sails broadcast to that room instead of socket.io-emitter.

noderman
  • 1,934
  • 1
  • 20
  • 36