101

How to best send additional data upon socket connection?

Client:

socket.on('connect',function(){ //I'd like set some values and pass them up to the node server. }); 

Node.js Server:

io.on('connection', function(client){ //I'd like to get the data here. }); 

For example sending a user name or email address etc.

7 Answers 7

86

You should send your data either in connect or on create:

var s = io('http://216.157.91.131:8080/', { query: "foo=bar" }); s.connect(); var c = io.connect('http://216.157.91.131:8080/', { query: "foo=bar" }); 

With the new version of socket.io, on server is where the things have been changed:

var io = require('socket.io')(server); io.use(function(socket, next) { var handshakeData = socket.request; console.log("middleware:", handshakeData._query['foo']); next(); }); 
Sign up to request clarification or add additional context in comments.

10 Comments

I've seen other people say to use socket.request.query, but that does not work for me on socket.io v1.7.2. Definitely have to use socket.request._query.
Why there is no documentation on this ? github.com/socketio/socket.io-client/blob/master/docs/…
For socket.io v1.7.3, I had to use socket.handshake.query (via this answer).
No way to send more than one parameter? Does anyone knows the syntax? Fox exemple { query: "foo=bar", "bar=foo" } won't work.
@Miquel solved using {query: 'var1='+foo+'&var2=bar'
|
36

I have a different approach - emit an event right after connecting, with the data:

socket.on('connect',function(){ // Send ehlo event right after connect: socket.emit('ehlo', data); }); io.on('connection', function(client){ // Receive ehlo event with data: client.on('ehlo', function(data) { }); }); 

You can hold a variable/object, and say, when there is no ehlo event with data, the other events are ignored until ehlo is sent.

If this does not satisfy, you can send data right when connecting, I won't copy the code but it is in this answer: https://stackoverflow.com/a/13940399/1948292

2 Comments

This is a good approach for passing data to identify a user, like an access token. You might also want to handle socket.on('reconnect', …) if your server needs data it might stop persisting after a disconnect.
I wanted to send some data to server every time the user got reconnected. This way is fantastic.
16

The connection events get fired as soon as the TCP connection is established. There's no way to send anything in between.

What you can do is to simply take the first message send by the server and put the data in that message. I'd strongly suggest to roll some thin protocol for this, so you would have multiple types of messages and use those to determine how the code should process the data.

This would be more extendable too, since it's fairly easy to come up with a generic architecture for that. If you want to wait for the userdata to come in first you can simply add some state to your connections.

8 Comments

Hey Ivo, Thanks a lot for getting back to me. Can you give me a bit more detail on how to achieve what you're saying? Thanks again!
Basically, I have a working chat app, where you can send to specific clients. The issue is that I have no way of matching up the sessionId with the user name. So, if you and I were chatting, instead of saying "Dan" and "Ivo" it'd show the client id's.
Can you give me a bit more information about your architecture / code? Where do the IDs come from and where do the names come from? Can't the app not just do a request to the server and ask for the usernames that are associated with the IDs?
username would come from a db(i.e. after a user logs in). ids come from client.sessionId. To be honest, I implemented my solution based on an answer you gave to a similar question. I add clients as they come in(on connect) to an array and remove them on disconnect. I pass the client ids down to the client on message and connect. It's working really well, so thanks a lot for that other post:) So, are you saying I should make a call to the db and attempt to match up the sessionid to a field in the db?
@Dan: Just store your user session in Redis and have the key stored in a cookie in the users browser. Fetch the cookie on socket connect and send it back to server.
|
10

this is my code on socket version 2.1.1

//client side var socket = io.connect(window.location.origin,{query:'loggeduser=user1'}); // server side io.socket.on('connection', function (socket) { console.log("loggeduser => " + socket.handshake.query.loggeduser); }); 

1 Comment

Works for version 3 too
8

this my code for sending query data to nodejs and server.io server client

var socket = io.connect(window.location.origin,{query:'loggeduser=user1'}); io.sockets.on('connection', function (socket) { var endp = socket.manager.handshaken[socket.id].address; console.log("query... " + socket.manager.handshaken[socket.id].query.user); }); 

query...user1

Comments

5

I found the answer located here really helpful in this regard: Send custom data along with handshakeData in socket.io?

Also brushing up on the following documentation helps explain ways to tie variables to the handshake object which can be accessed from the socket object during the connection: https://github.com/LearnBoost/socket.io/wiki/Authorizing#global-authorization

Comments

0

I'm assuming you will use SSL.

Using querystrings to send sensitive data is not a good security practice (why?). I think that if you need to send non-sensitive data, then Miquel answer is the fastest and more easy one, but if sensitive data is what you need to send, then something like Daniel W. is the best approach to take.

For an authentication approach, you can take a look at this github project (socketio-auth) which, beyond the fact that it is currently with no maintenance, can give you a good idea of how to deal with the problem.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.