Rectangle 27 18

A couple of ways to send feedback to a specific client over socket.io include:

As stated by pkyeck, save all clients to an Object, so you can send to these specific clients later in your route handlers, e.g.:

var sessionsConnections = {};
sio.on('connection', function (socket) {
  // do all the session stuff
  sessionsConnections[socket.handshake.sessionID] = socket;
});
  • or, use socket.io's built in support for rooms - subscribe each client to a room on connection and send via this room within route handlers, e.g.: sio.on('connection', function (socket) { // do all the session stuff socket.join(socket.handshake.sessionID); // socket.io will leave the room upon disconnect }); app.get('/', function (req, res) { sio.sockets.in(req.sessionID).send('Man, good to see you back!'); });

Note that both these example solutions assume that socket.io and express have been configured to use the same session store and hence refer to the same session objects. See the links above and below for more details on achieving this:

Just want to say that using the session id as a room was a great suggestion. Helped me solve a problem I was having, so thanks :)

seems like socket.io 1.0 has built in support for the room per socket approach: socket.io/docs/rooms-and-namespaces

The room should take care of clustering. Saving sockets in local memory like other answers can lead to memory leak and can't scale.

node.js - Sending message to specific client with socket.io and empty ...

node.js express socket.io
Rectangle 27 52

to send a message to a specific client save every one that connects to the server in an Object.

var socketio = require('socket.io');
var clients = {};
var io = socketio.listen(app);

io.sockets.on('connection', function (socket) {
  clients[socket.id] = socket;
});

then you can later do something like this:

var socket = clients[sId];
socket.emit('show', {});

that doesnt work. i have made a simple test: var soc; io.sockets.on('connection', function (socket) { soc = socket; }); outside from every rout. and than in my upload function i have used soc.emit('news', 'bla') nothing happens....

as i said before: you can't send events while uploading a file. but this methods works and you can send messages to specific clients, when you have the corresponding id.

:-/ sorry i misunderstood you. so there is no way to trigger a message to a specific client from a route function?

yes, there is. you have to save all clients that connect to your server in the clients-object (see example) and when you have the socket-id, you can access the socket directly through the object. but you CAN'T do that while uploading...

what exactly are you trying to do? delete the old connection? just do a delete clients[socketId]; when the client disconnected and it'll be removed from clients hash.

node.js - Sending message to specific client with socket.io and empty ...

node.js express socket.io
Rectangle 27 148

socket.id
io.sockets.socket(savedSocketId).emit(...)

First you need to set Redis store as the store so that messages can go cross processes:

var express = require("express");
var redis = require("redis");
var sio = require("socket.io");

var client = redis.createClient()
var app = express.createServer();
var io = sio.listen(app);

io.set("store", new sio.RedisStore);


// In this example we have one master client socket 
// that receives messages from others.

io.sockets.on('connection', function(socket) {

  // Promote this socket as master
  socket.on("I'm the master", function() {

    // Save the socket id to Redis so that all processes can access it.
    client.set("mastersocket", socket.id, function(err) {
      if (err) throw err;
      console.log("Master socket is now" + socket.id);
    });
  });

  socket.on("message to master", function(msg) {

    // Fetch the socket id from Redis
    client.get("mastersocket", function(err, socketId) {
      if (err) throw err;
      io.sockets.socket(socketId).emit(msg);
    });
  });

});

I omitted the clustering code here, because it makes this more cluttered, but it's trivial to add. Just add everything to the worker code. More docs here http://nodejs.org/api/cluster.html

Thanks it was helpful. I just had to use an array instead: io.of('/mynamespace').sockets[socketID].emit(...) (don't know if it's because I'm using a namespace)

on clustered environment, how do I make sure that the correct process that the socket belongs to is sending the messsage ?

How about a sticky session courtesy of NGINX or HAProxy @Gal Ben-Haim?

javascript - Send message to specific client with socket.io and node.j...

javascript node.js websocket socket.io server-side
Rectangle 27 147

socket.id
io.sockets.socket(savedSocketId).emit(...)

First you need to set Redis store as the store so that messages can go cross processes:

var express = require("express");
var redis = require("redis");
var sio = require("socket.io");

var client = redis.createClient()
var app = express.createServer();
var io = sio.listen(app);

io.set("store", new sio.RedisStore);


// In this example we have one master client socket 
// that receives messages from others.

io.sockets.on('connection', function(socket) {

  // Promote this socket as master
  socket.on("I'm the master", function() {

    // Save the socket id to Redis so that all processes can access it.
    client.set("mastersocket", socket.id, function(err) {
      if (err) throw err;
      console.log("Master socket is now" + socket.id);
    });
  });

  socket.on("message to master", function(msg) {

    // Fetch the socket id from Redis
    client.get("mastersocket", function(err, socketId) {
      if (err) throw err;
      io.sockets.socket(socketId).emit(msg);
    });
  });

});

I omitted the clustering code here, because it makes this more cluttered, but it's trivial to add. Just add everything to the worker code. More docs here http://nodejs.org/api/cluster.html

Thanks it was helpful. I just had to use an array instead: io.of('/mynamespace').sockets[socketID].emit(...) (don't know if it's because I'm using a namespace)

on clustered environment, how do I make sure that the correct process that the socket belongs to is sending the messsage ?

How about a sticky session courtesy of NGINX or HAProxy @Gal Ben-Haim?

javascript - Send message to specific client with socket.io and node.j...

javascript node.js websocket socket.io server-side
Rectangle 27 73

Well you have to grab the client for that (surprise), you can either go the simple way:

var io = io.listen(server);
io.clients[sessionID].send()

Which may break, I hardly doubt it, but it's always a possibility that io.clients might get changed, so use the above with caution

Or you keep track of the clients yourself, therefore you add them to your own clients object in the connection listener and remove them in the disconnect listener.

I would use the latter one, since depending on your application you might want to have more state on the for the clients anyway, so something like clients[id] = {conn: clientConnect, data: {...}} might do the job.

Ivo, can you point to a more complete example or elaborate a bit? I'm eager to understand this approach, but I'm not sure I recognize the variables/objects you're using in this example. In clients[id] = {conn: clientConnect, data: {...}}, is clients[id] part of the io object as seen in io.clients[sessionID] above? Also what is the clientConnect object? Thanks.

javascript - Send message to specific client with socket.io and node.j...

javascript node.js websocket socket.io server-side
Rectangle 27 73

Well you have to grab the client for that (surprise), you can either go the simple way:

var io = io.listen(server);
io.clients[sessionID].send()

Which may break, I hardly doubt it, but it's always a possibility that io.clients might get changed, so use the above with caution

Or you keep track of the clients yourself, therefore you add them to your own clients object in the connection listener and remove them in the disconnect listener.

I would use the latter one, since depending on your application you might want to have more state on the for the clients anyway, so something like clients[id] = {conn: clientConnect, data: {...}} might do the job.

Ivo, can you point to a more complete example or elaborate a bit? I'm eager to understand this approach, but I'm not sure I recognize the variables/objects you're using in this example. In clients[id] = {conn: clientConnect, data: {...}}, is clients[id] part of the io object as seen in io.clients[sessionID] above? Also what is the clientConnect object? Thanks.

javascript - Send message to specific client with socket.io and node.j...

javascript node.js websocket socket.io server-side
Rectangle 27 59

each socket joins a room with a socket id for a name, so you can just

io.to(socket#id).emit('hey')

This is the good answer that works in distributed systems as well.

This is the best answer and works w/ newer versions of socket.io. There's a nice cheat sheet here: stackoverflow.com/questions/10058226/

This should be the answer. Wish it was higher!

note that this is a 'broadcast' type of emiting an event. so if you try to set a callback to this, you'll have an error. if you need to send an event to a specific socket with a callback, then use @PHPthinking's answer and use io.sockets.connected[socketid].emit();. Tested with 1.4.6.

This should be the accepted answer, it's neat, simple and working smoothly!

javascript - Send message to specific client with socket.io and node.j...

javascript node.js websocket socket.io server-side
Rectangle 27 55

It's as easy as:

client.emit("your message");

What we all need is in fact a full example, and that's what follows. This is tested with the most recent socket.io version (2.0.3) and it's also using modern Javascript (which we should be all using by now).

The example is comprised of two parts: a server and a client. Whenever a client connects, it starts receiving from the server a periodic sequence number. A new sequence is started for each new client, so the server has to keep track of them individually. That's where the "I need to send a message to a particular client" comes into play. The code is very simple to understand. Let's see it.

server.js

The server starts listening on port 8000 for incoming connections. When one arrives, it adds that new client to a map so it can keep track of its sequence number. It also listens for that client's disconnect event, when it'll remove it from the map.

Each and every second, a timer is fired. When it does, the server walks through the map and sends a message to every client with its current sequence number. It then increments it and stores the number back in the map. That's all that is to it. Easy peasy.

The client part is even simpler. It just connects to the server and listens for the seq-num message, printing it to the console every time it arrives.

client.js
const
    io = require("socket.io-client"),
    ioClient = io.connect("http://localhost:8000");

ioClient.on("seq-num", (msg) => console.info(msg));
npm install socket.io
npm install socket.io-client
node server

Open other terminal windows and spawn as many clients as you want by running:

node client

Is port 8000 the norm for socketio in production?

Sorry I took so long to reply back, @ingo. 8000 is a common port used by the Node community when testing both websockets or HTTP servers (3000 is also common). Of course you could use it in production, but I'm not sure how common that is... anyway, you can just use any port really, as long as your gateways/load balancers/etc are prepared for that.

Thanks a lot man! =)

javascript - Send message to specific client with socket.io and node.j...

javascript node.js websocket socket.io server-side
Rectangle 27 54

It's as easy as:

client.emit("your message");

What we all need is in fact a full example, and that's what follows. This is tested with the most recent socket.io version (2.0.3) and it's also using modern Javascript (which we should be all using by now).

The example is comprised of two parts: a server and a client. Whenever a client connects, it starts receiving from the server a periodic sequence number. A new sequence is started for each new client, so the server has to keep track of them individually. That's where the "I need to send a message to a particular client" comes into play. The code is very simple to understand. Let's see it.

server.js

The server starts listening on port 8000 for incoming connections. When one arrives, it adds that new client to a map so it can keep track of its sequence number. It also listens for that client's disconnect event, when it'll remove it from the map.

Each and every second, a timer is fired. When it does, the server walks through the map and sends a message to every client with its current sequence number. It then increments it and stores the number back in the map. That's all that is to it. Easy peasy.

The client part is even simpler. It just connects to the server and listens for the seq-num message, printing it to the console every time it arrives.

client.js
const
    io = require("socket.io-client"),
    ioClient = io.connect("http://localhost:8000");

ioClient.on("seq-num", (msg) => console.info(msg));
npm install socket.io
npm install socket.io-client
node server

Open other terminal windows and spawn as many clients as you want by running:

node client

Is port 8000 the norm for socketio in production?

Sorry I took so long to reply back, @ingo. 8000 is a common port used by the Node community when testing both websockets or HTTP servers (3000 is also common). Of course you could use it in production, but I'm not sure how common that is... anyway, you can just use any port really, as long as your gateways/load balancers/etc are prepared for that.

Thanks a lot man! =)

javascript - Send message to specific client with socket.io and node.j...

javascript node.js websocket socket.io server-side
Rectangle 27 53

each socket joins a room with a socket id for a name, so you can just

io.to(socket#id).emit('hey')

This is the good answer that works in distributed systems as well.

This is the best answer and works w/ newer versions of socket.io. There's a nice cheat sheet here: stackoverflow.com/questions/10058226/

This should be the answer. Wish it was higher!

note that this is a 'broadcast' type of emiting an event. so if you try to set a callback to this, you'll have an error. if you need to send an event to a specific socket with a callback, then use @PHPthinking's answer and use io.sockets.connected[socketid].emit();. Tested with 1.4.6.

This should be the accepted answer, it's neat, simple and working smoothly!

javascript - Send message to specific client with socket.io and node.j...

javascript node.js websocket socket.io server-side
Rectangle 27 33

On socket.io >=1.0, after the connect event has triggered:

var socket = io('localhost');
var id = socket.io.engine.id
socket.on 'connect'

@webjay yeah, property is only assigned on connect event, not before.

that worked for me! did NOT have to use it on socket.on 'connect'

javascript - how to get session id of socket.io client in Client - Sta...

javascript socket.io
Rectangle 27 1

In Socket.IO 1.0, .to() and .in() are the same. And others in the room will receive the message. The client sends it won't receive the message.

Since .to() and ,in are the same, then what would happen when I create a room with the exact same name as some socket's id. What would socket.broadcast.to(socketid) for example do then?

Socket.io rooms difference between broadcast.to and sockets.in - Stack...

socket.io
Rectangle 27 14

The function passed to .on is called for each socket to do the initialization (binding events etc), and socket refers to that current socket. This will be client 1 when you receive a push message, because the handler function is bound to the push event of that socket - you bound that function when client 1 connected (where socket refers to client 1).

io.sockets refers to all sockets connected, so including client 2 in your case.

it worked like a charm, thanks a ton :)

javascript - socket.io client not receiving messages from server - Sta...

javascript node.js websocket socket.io
Rectangle 27 7

io.sockets.on(..)
app/update

2) io.sockets.socket(id); should not be used, it should have been socket.emit('new', 'hello')

okay great, this was also a problem io.connect('localhost:80/socket.io/socket.io.js'); but what when i want to send messages during the upload? then I need to store the client ID and use io.sockets.socket(socket.id).emit('new', 'hello'); or not?

as far as i know the socket connection isn't disconnected while uploading a file via form.

okay great and the last question. is it possible die empty the message queue? when i reenter the view i receive all the old massages...

@vboy which message queue are you talking about? The message queue that socket.io maintains internally for messages that are not received by the client?

node.js - Sending message to specific client with socket.io and empty ...

node.js express socket.io
Rectangle 27 31

Yes!!!, previously io.sockets.sockets[socketid].emit() worked, but this gave me undefined object errors in newer version of socket.io. Changing to io.sockets.connected works.

For those using TypeScript, this is currently the 'canonical' API for this according to the typings.

javascript - Send message to specific client with socket.io and node.j...

javascript node.js websocket socket.io server-side
Rectangle 27 30

Yes!!!, previously io.sockets.sockets[socketid].emit() worked, but this gave me undefined object errors in newer version of socket.io. Changing to io.sockets.connected works.

For those using TypeScript, this is currently the 'canonical' API for this according to the typings.

javascript - Send message to specific client with socket.io and node.j...

javascript node.js websocket socket.io server-side
Rectangle 27 70

In socket.io 0.8, you should attach events using io.sockets.on('...'), unless you're using namespaces, you seem to be missing the sockets part:

io.listen(fileserver).sockets.on('connection', handler)

It's probably better to avoid chaining it that way (you might want to use the io object later). The way I'm doing this right now:

// sockets.js
var socketio = require('socket.io')

module.exports.listen = function(app){
    io = socketio.listen(app)

    users = io.of('/users')
    users.on('connection', function(socket){
        socket.on ...
    })

    return io
}

Then after creating the server app:

// main.js
var io = require('./lib/sockets').listen(app)

Great answer, trying to port this to krakenJS but the socket.io module never starts :/

We arent using 'return io' right? it's just for the var io.

Separating file server and socket.io logic in node.js - Stack Overflow

node.js socket.io
Rectangle 27 5

In socket.io 1.0, this is how it would work. It may work for lower versions, but I cannot guarantee it.

socket.to(socket_id_here).emit('new', 'hello');

This works because socket.io automatically adds a socket to a room with the socket's id on connection.

Also, if you plan to upgrade to version 1.0, there are a lot of changes to the api, so you'll sometimes have to change some code to make it work in 1.0.

node.js - Sending message to specific client with socket.io and empty ...

node.js express socket.io
Rectangle 27 17

socket.emit('message', 'check this');

//or you can send to all listeners including the sender

io.emit('message', 'check this');
socket.broadcast.emit('message', 'this is a message');

//or you can send it to a room

socket.broadcast.to('chatroom').emit('message', 'this is the message to all');

javascript - Send message to specific client with socket.io and node.j...

javascript node.js websocket socket.io server-side
Rectangle 27 17

socket.emit('message', 'check this');

//or you can send to all listeners including the sender

io.emit('message', 'check this');
socket.broadcast.emit('message', 'this is a message');

//or you can send it to a room

socket.broadcast.to('chatroom').emit('message', 'this is the message to all');

javascript - Send message to specific client with socket.io and node.j...

javascript node.js websocket socket.io server-side