36

I´m going crazy with socket.io! Documentation is so bad it's simply not true.

I want to send a feedback to specific client over socket.io

My server side looks like this:

app.get('/upload', requiresLogin, function(request, response) {
    response.render('upload/index.jade');
    io.sockets.on('connection', function (socket) {
        console.log('SOCKET ID ' + socket.id);
        io.sockets.socket(socket.id).emit('new', 'hello');
    });
});

and the client side looks like this:

$(document).ready(function() {
    var socket = io.connect('http://localhost:80/socket.io/socket.io.js');
    socket.on('new', function (data) { 
        console.log(socket.id);
        console.log(data); 
        //$('#state').html(data.status);
    });
});

but the client does simply nothing. I have tried nearly everything. Can someone tell me what I am doing wrong, please! :(

0

9 Answers 9

53

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', {});
Sign up to request clarification or add additional context in comments.

10 Comments

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.
|
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!');
    });
    

Acknowledgement:

http://www.danielbaulig.de/socket-ioexpress/#comment-1158

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:

https://github.com/LearnBoost/socket.io/wiki/Authorizing

3 Comments

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.
7

2 things

1) You should really place your io.sockets.on(..) outside your app/update route to prevent adding multiple listeners for clients.

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

4 Comments

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?
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.

Comments

4

The correct way to do this in Socket.io 1.0+ is:

io.to(users_socket_id).emit('new', 'hello');

You can also substitute a room name for 'users_socket_id' to emit to a specific socket.io room.

Comments

2

First of all, you cannot use socket.id on client side.

And then change the line

var socket = io.connect('http://localhost:80/socket.io/socket.io.js');

to

var socket = io.connect('http://localhost:80/');

Comments

0

I believe io.sockets.socket has been removed and has been a problem in Socket.IO (https://github.com/socketio/socket.io/issues/1618).

You can use io.sockets.connected[socket.id] and store the socket.id to reference with the user via username:

var usernames = {};
usernames[username] = socket.id;
// Sending the message
io.sockets.connected[usernames[username]].emit(...);

I don't see it anywhere on the documentation so I can see how this hasn't been answered. Also, if you don't have any reference via usernames, you can instead try:

users[socket.id] = socket.id;

to duplicate the key and value for easy access.

There is also possibly another way by using io.clients as described below, but I haven't used that method.

OTHER SOLUTION: Send message to specific client with socket.io and node.js

Comments

0

Have you tried using?

var socket = io.connect('http://localhost:80/');

Comments

0

i tired with the latest version of node and socket.io below i am going to post complete code

  <ul id="messages"></ul>
<form action="">
  <input id="id1"  /><button>Send</button>
</form>
<script src="https://cdn.socket.io/socket.io-1.2.0.js"></script>
<script src="http://code.jquery.com/jquery-1.11.1.js"></script>
<script>

  var io = io.connect();
  $('form').submit(function(){
    io.emit('drumevent', $('#id1').val());
    $('#id1').val('');
    return false;
  });
  io.on('drumevent', function(msg){
  console.log(msg);



    $('#messages').append($('<li></li>').text(msg.message+'    quantity = '+msg.quantity));
  });
</script>

server side code

  var usernames = {};io.on('connection', function(socket){usernames["username"] = socket.id;
socket.on('drumevent', function(msg){     
var socketId = socket.id;io.to(socketId).emit('drumevent', data);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.