divillysausages.com

An intro to Socket.io

Recently I've been playing around with Socket.io, which, according to the site, enables real-time bidirectional event-based communication. Damn, that's some sexy copy.

Basically you can use it as a real-time server, and one of the things that makes it so interesting is that it works on pretty much every platform, browser, or device. I thought I'd write an intro on the subject as I found their documentation to be lacking in some cases and confusing in others; I frequently found myself with questions that I only answered through trial-and-error and reading the source code.

And you should never have to read the source code.

TypeScript!

I'm using TypeScript, so one of the first things I did was try and hook myself up with some definition files so I could get some code completion. I found the excellent DefinitelyTyped project and related tsd, or TypeScript Definition manager.

Unfortunately, after scratching my head for a day or two, I finally realised that the d.ts files were for an old version. Sadface.

So I learned how to create TypeScript definition files, and went through the code and created new definitions for the latest version (1.3.5 as of time of writing). If the pull request hasn't been accepted yet, then you can find them at the bottom of this post.

They're even commented to boot.

AND I went out of my way to describe the options object, which nobody apparently does, but blow trawling through documentation and READMEs for a lark. If it's not code-completed, it doesn't exist.

The setup

For the setup, I worked from the Chat example on the Socket.io website, with the exception that I didn't use Express (on a side node, Express is great and all, for beginners, one framework at a time, please). You should be able to follow that example in order to get setup. To install Socket.io (locally), just use:

npm install socket.io

Like in my tutorial for Using Phaser with Visual Studio Code I'm not using Express, I'm using node-static (as all it does is serve files from whatever directory you throw at it, so it's a perfect light-weight solution). If you want to use that, then install via:

npm install node-static

Then set up your app.js file like this:

import nodeStatic 	= require( 'node-static' );
import http			= require( 'http' );
import socketIO		= require( 'socket.io' );

// create our file server config
var file = new nodeStatic.Server( 'bin', { // bin is the folder containing our html, etc
	cache:0,	// don't cache
	gzip:true	// gzip our assets
});

// create our server
var httpServer = http.createServer( function( request, response ) {
	request.addListener( 'end', function() {
		file.serve( request, response );
	});
	request.resume();
}).listen( 4000 );

That's it. From this point out, it's all Socket.io. Note that when we call http.createServer(), we save the returned Server as our httpServer var; we'll need that later when binding Socket.io.

The basics

First of all: connecting. On the server, setup Socket.io like this:

var sio = socketIO();
sio.serveClient( true ); // the server will serve the client js file
sio.attach( httpServer );

// listen for a connection
sio.on( 'connection', function( socket ){
	
	console.log( 'User ' + socket.id + ' connected' );
});

To explain a bit:

On the client, you embed the client side code via:

<script src="/socket.io/socket.io.js"></script>

That particular path is if you're using sio.serveClient( true ). Otherwise, if you're serving it yourself, replace it with the right path. To connect to our server, it's simply:

var clientSocket = io();

Start your server (node app.js), go to http://localhost:4000 in your browser, and you should see something like

User 8fyIQvC4HUYEpZeDAAAA connected

in your console. Eassssssy.

Namespaces and rooms

A quick note on namespaces and rooms and what the difference between the two is. By default, when you call io() on the client to connect, what you're actually calling is io( 'http://localhost:4000/' ), as by default, it will take the host and port of the current page, and connect to the default namespace, which is /. If you wanted to connect to a namespace called 'foo', then you'd have to call io( 'http://localhost:4000/foo' ).

So what's a namespace?

It's a way of separating your code. It's one socket to a namespace, so if you called:

var news = io( 'http://localhost:4000/news' );
var chat = io( 'http://localhost:4000/chat' );

while it might use the same physical TCP connection, they're two separate objects - news can't send messages to /chat and vice-versa.

The main namespace, /, is created by default, and all clients join it, even if they connect to another namespace.

On the server, when a namespace emits an event, all sockets connected to the namespace receive it.

After that, we have rooms. Rooms are essentially grouping of sockets, and let you send messages to a subgroup of a namespace. You only need to know the name of a room to send a message to it. Unlike with namespaces, sockets can join as many rooms as they want.

Think of it like this: the Socket.io server is your game website (e.g. all-poker.com), namespaces are each game (e.g. /texas, /omaha), and rooms are private rooms within each game (e.g. table1, table2, etc).

The differences in list form:

Or in picture form:

Explaining namespaces and rooms

Sending a message to the client

To send a message to the client, we call emit() on the socket, passing the event name, and whatever data we want to send:

socket.emit( 'greetings', 'Hello from the server!', socket.id );

Then on the client, we add a listener for the 'greetings' event:

clientSocket.on( 'greetings', function( message, id ) {
	console.log( 'Got a message from the server: "' + message + "', my ID is: " + id );
});

Note that we're sending the socket.id to the client with the emit() call. We could have also called clientSocket.id, but we can use this technique to send the IDs of other sockets, which will become useful later. The id is a auto-generated ID set when the socket connects. It'll be different everytime, so there's no point storing it.

Also note that the only parameter that's actually required is the event name, in this case 'greetings'. Anything after that is sent to the client as parameters for the callback - with one exception: if the last argument is a function, then it'll be used as an ack - called when receipt of the message is acknowledged. This is a bit more advanced, so for the minute, we don't care.

Sending a message to the server

Sending a message to the server is exactly the same. On the client:

clientSocket.emit( 'message', 'Hello from the client' );

While on the server, we need to add any listeners to the socket that we get during the 'connection' event:

// listen for a connection
sio.on( 'connection', function( socket ){

	console.log( 'User ' + socket.id + ' connected' );
	
	// listen for the 'message' event
	socket.on( 'message', function( msg ){
		
		console.log( 'User ' + this.id + ' sent message "' + msg + '"' );
	});
});

Note that in the socket callback, you can use this to reference the socket (or socket as it'll be bound).

This is about the height of what you need to do on the client. Everything after this (sending messages to different people etc) happens on the server.

Sending a message to everyone in the namespace

To send a message to everyone, instead of calling socket.emit(), which only sends a message to that socket, we get the namespace itself to send the event.

In this example, we're using the sio Server object, created when we created Socket.io on the server.

socket.on( 'tellEveryone', function( msg ){

	sio.emit( 'heyEveryone', msg, socket.id ); // pass the socket.id so other client know who it's from
});

The sio.emit() method here is actually a helper function that gets the default namespace (/) and calls emit() on that. The following 3 calls all do the same thing:

sio.emit( 'heyEveryone', msg, socket.id );
sio.sockets.emit( 'heyEveryone', msg, socket.id ); // sio.sockets is a reference to the main "/" namespace
sio.of( '/' ).emit( 'heyEveryone', msg, socket.id ); // of( '/' ) is how we reference a namespace, in this case the main "/" one

Notice that last of( '/' ) call? That's how we reference other namespaces. Remember how I said sockets in one namespace couldn't send messages to sockets in other namespaces? This is how you get around that:

socket.on( 'tellNamespace', function( msg, namespaceName ){

	sio.of( namespaceName ).emit( 'heyEveryone', msg, socket.id ); 	// NOTE: namespace will be created if it doesn't exist
});

Sending a message to everyone in a room

To send a message to a room, you need to know it's name. You don't actually need to have joined the room to send a message to it, but you do if you want to receive messages from that room.

socket.on( 'tellRoom', function( msg, roomName ) {

	socket.to( roomName ).emit( 'heyThere', msg, socket.id ); // NOTE: room will be created if it doesn't exist
});

You can also use in( roomName ) instead of to() if you wish.

You can also send to multiple rooms by chaining the to() calls:

socket.on( 'tellRooms', function( msg, room1Name, room2Name ){
	
	socket.to( room1Name ).to( room2Name ).emit( 'heyThere', msg, socket.id );
});

Note that on the client, if they've joined multiple rooms, when they get a message, they won't actually know which room (if any) sent it, so it's generally a good idea to pass the room name as one of the parameters.

Sending a message to everyone except you

The socket has a broadcast flag, that when used will send the event to everyone in the namespace/room except for yourself. For a namespace:

socket.on( 'broadcastMsg', function( msg ) {

	socket.broadcast.emit( 'broadcastFrom', msg, socket.id );
});

or for a room:

socket.on( 'broadcastMsg', function( msg, roomName ) {

	socket.to( roomName ).broadcast.emit( 'broadcastFrom', msg, socket.id );
});

Sending a message to another user

To send a message to another user, we can go about it two ways: we can get the socket of the other user from the connected dictionary on our namespace and call emit() on it:

socket.on( 'sendToUser', function( msg, userID ){
	
	// try and get the socket from our connected list
	var otherSocket = sio.sockets.connected[userID]; // NOTE: sockets is the default "/" namespace
	if( otherSocket )
		otherSocket.emit( 'messageFromUser', msg, socket.id );
});

But remember when I said it's a good idea for the client to know the IDs of other clients? This is because when a socket connects, one of the things that it does it join a room with the same name as its ID. So to send a message to a client, we can use the same logic as sending a message to a room:

socket.on( 'sendToUser', function( msg, userID ){

	socket.to( userID ).emit( 'messageFromUser', msg, socket.id );
});

Technically this means that if we join() this room, we'd be privy to all the private messages sent to this user, which opens up all sorts of interesting possibilities.

Getting the IDs of connected users

If you want to send a list of all the socket IDs in a particular namespace, you can go through the connected dictionary on the namespace:

var sids = keys( sio.sockets.connected ); // sockets = default "/" namespace

To send all the IDs for a particular room, you need to go through the adapter property on the namespace:

var socketsInRoom 	= sio.sockets.adapter.rooms[roomName]; // sockets = default "/" namespace
var sids 			= ( socketsInRoom ) ? keys( socketsInRoom ) : []

Nicknames

To enable nicknames, you simply need to keep a dictionary of socket ids => nicknames on the server. Then you can either do two things:

Fin

So there you have it! You should be set up for firing messages left and right. If there's another scenario you want covered, leave a comment, and I'll add it in.

In the meantime, check out Socket.io and download the v1.3.5 TypeScript definition files below.

Files

Comments

Michael

The best introduction to socket.io that i've ever seen.

Adrien

I agree with Michael, this "introduction" is a nice summary of Socket.io, very helpful thanks

Kev

That's what I was looking for !! Great job !

Sir

Excellent, very clear and helpful.

Varoon

Nicely explained in a very simple form. I am looking for a tutorial that maps the theory of websockets and TCP to the socket.io API. You are probably the best guy to do it. That with this tutorial would be all that one would need to be a good socket.io coder!

Damian Connolly

Hi Varoon, do you mind being more precise as to what you're looking for? The whole point of Socket.io is to handle TCP so you don't have to. Aside from the parameters that are passed to the underlying Engine.io instance, you generally don't need to do any heavy lifting.

Marco

Great job, clear and useful.

Julio Pari

D: ni en la documentacion explican mejor :D

imma hanitya

the best documentation, salute !!

balwant padwal

Nice Tutorial for new User..

Em

This is the most beginner-friendly socket.io tutorial i have seen.

Gayathri G

It really helps me.Thanks dude

ZAIN

In the examples you passed client id to send message to specific user but how are you storing the ids on client side

Damian Connolly

Hi Zain,
A simple Object on the client is enough to store your ID/nickname. Something like:

var nicknames = {};

// when you get a nickname/id:
nicknames[socket.id] = nickname

As the socket.id changes every time, you don't need to stock it, so you can just recover them all when you connect.

Manoj

I'm new to socket.io. I'm struggling to implement multiple chat. so I want implemented code. Please send code

Damian Connolly

Hi Manoj,
In the Getting Started section of Socket.io, you can find a step-by-step guide on creating a chat application. What have you tried?

Fabien

Merci pour ce tuto ! Simple et complet

hamidkardorost

great tutorial . thank you
one thing that's not covered well in web is "Authentication Socket"
it would be nice if you could add some tuts about auth as well

Damian Connolly

Hi Hamidkardorost,
What do you mean by "authentication"? Personally, I simply have an event like any other where the user sends their ID/Token. Prior to that they can be marked as a guest.

There are other approaches as well, such as https://auth0.com/blog/auth-with-socket-io/ for example, which uses JSON Web Tokens

R Martin

Socket.io should use this as its documentation

hi,my name is Hardik

can you please give a more description in Nicknames part with some sample code example ?

Damian Connolly

Hi Hardik,
There's really no special logic to take into account - as in there's no "nickname" event built-in to Socket.io, so how you want to handle it is up to you. Assuming a simple drop-in/drop-out setup where there's no login or anything, one way would be:

  • On the server hold an object where the key is the socket ID, and the value is the nickname for the socket. As the socket ID changes every time you reconnect, there's no need to persist this in a DB or anything
  • When a user connects, they send an event (e.g. "setNickname") with their chosen nickname. We update the object and notify everyone else in the room
  • When a user disconnects, we clear their key from the object as there's no point in keeping it
  • For a new user to know everyone's nickname, you can do one of two things:
    • 1) Send the socket ID/nickname object to them on connect, and the user updates it locally when someone else joins the room
    • 2) When a user sends a message, the server looks up their nickname in the object and sends it along with the message

That's pretty much it

In terms of keeping your nickname between sessions, you can simply save it in LocalStorage.

bluemix

really, as mentioned above, one of the best tutorial. i found it randomly on Google Images. thanks a lot.

Alok

WOW. Wonderful introduction. Have you done other writeups? Specially on understanding CORS etc.

Damian Connolly

Hi Alok,
You can find all my other content listed on the Archive page.

I don't have anything on CORS, but you can find a nice writeup at https://www.html5rocks.com/en/tutorials/cors/.

Jai

When I connect to a namespace, connection event is being fired in the default namespace. Why so?

Damian Connolly

Hi Jai,
As far as I can tell, this is by design. As I noted above:

The main namespace, /, is created by default, and all clients join it, even if they connect to another namespace.

I'm not 100% on whether this is because you connect to the default namespace before being shuffled off to the sub namespace, or if it's to allow you a way of knowing about and contacting all connected sockets.

Either way, it can be quite useful, and pretty easy to ignore if you don't want to use it.

Jeff

How do you use socket.io to push random data updates to client subsequent to the initial client connection event? All examples of emit seem to assume they are triggered on client connection, not a server-side event.

Damian Connolly

Hi Jeff,
How you send messages after the initial connection really depends on your program. The vast majority of the time, you'll be sending clients messages in relation to an event, normally a client event - e.g. ClientA sends a chat message.

The reason why it looks like we're doing everything through the client connection is because that's normally where we'd add all the callbacks for that client. e.g. we can have something like:

sio.on( 'connection', function( socket ){

	console.log( 'User ' + socket.id + ' connected' );
	
	// add our event listeners
	socket.on( 'chat', onClientChat );
	socket.on( 'move', onClientMove );
	socket.on( 'enterRoom', onClientEnterRoom );
	socket.on( 'changeName', onClientChangeName );
	
});

These are all the events that your client can call, which can then trigger data updates for other clients. For example, for the changeName event, you might send a message to all other connected clients so they know the new name. While the listeners are added in the connection event, they're not necessarily called there and then.

Otherwise, you might have an event on the server that's triggered every so often (e.g. using setInterval) that will automatically sent a message (or data) to all connected users (or only those in particular rooms). Again, how you trigger server side events is really dependant on how you want to do things.

Jeff

Thank you very much for your answer. I have in fact solved my problem and now am able to emit messages at will to connected clients independent of the "on connection" loop. Among the various use cases for socket.io it seems that most of the emphasis is on game play or chat room like applications most of which are based on client-driven interactions while use cases which are server-driven, like updating consoles, dashboards with real-time data from sensors or node express application data are not emphasized. Again thank you for all your efforts. Socket.io owes you a debt of gratitude. J'aime Bordeaux, vous avez la chance d'habitez la

Damian Connolly

Thank you, you're welcome!

Most examples are simple chat-based applications simply because it's the easiest example to show off what Socket.io capable of. Once you get the hang of it though, it's easy enough to have nearly anything trigger an update.

ML

The best intro for the socket.io. thanks a lot.

Murilo V

Really nice Tutorial that explained all my doubts. Even better than the socket.io docs for a beginner.
Thanks

Somp

the best socket tutorial i have seen. thanks a lot

Hari

Hi,
I wanted to build a private chat just like the concept of facebook. When the user clicks on certain name(another user) , it creates a room for the them and conversation should exist only between them. I have logged in users both side of browser. How to handle this and make dynamic room for 2 users? How the client recognize another client in my case so that they could send message to one another.
Could you help me on this? Just idea

Thanks alot

Damian Connolly

Hi Hari,
The example for sending a message to another user should be sufficient for this. If it's just one-to-one chat, you don't need to create a room for them; just send messages between them directly. I'd go so far as to say that all messages are private unless they're scoped to a room.

For example, on your server, you might have a listener like so:

// either toUserID will be null or roomID will be
socket.on( 'sendMsg', function( msg, toUserID, roomID ){

	if( toUserID )
		socket.to( toUserID ).emit( 'receiveMsg', msg, socket.id ); // private msg
	else if( roomID )
		socket.to( roomID ).emit( 'receiveMsgFromRoom', msg, socket.id, roomID ); // msg to room
});

Now all you have to do is call sendMsg and pass either a toUserID for a private msg, or a roomID if you want to make it a room chat (where other people might be). Listen for the receiveMsg and receiveMsgFromRoom events and you're golden.

Does that make sense?

Hari

Hello Damian,
Thanks for the response. I got the idea. But I still could not emit the event to another userId.
For example :

io.to(toUser).emit('private message', {
	message: msg,
	user: socket.username,
	date: moment().valueOf() //date: moment(new Date()).format('YYYY-MM-DD, hh:mm a')
});

Here, toUser is the user whom I want to send message, but I could not grab his socket id so that i could send message. Or, I might do another way. When I click the user in client side, I want to create a room for both of us. But, I want to restrict other users to join. Meaning, if the length of the room is 2, I dont want to let other join that room. Is there any way to restrict that way?

Can you help me in either of the way?
Thank you so much again..

Damian Connolly

Hi Hari,
In order to send the right user a message - or indeed do anything with them, including creating a room - you'll need some form of unique identifier. Happily, the socket ID is just that, so it's simply a question of getting that to the client so they can use it. Here's how I would do it:

  • UserB connects to the main chat room. The server sends everyone a message saying that UserB has joined, their nickname X, and their socket ID
  • UserA receives the message and stores UserB's socket ID
  • The server also sends the nicknames and socket IDs of all connected users to UserB, so they know who's in the room
  • UserA wants to send a private message to UserB, and so sends a message to the server with socket ID that they received: clientSocket.emit( 'sendMsgTo', {msg:'Hello UserB', to:userB.socketID} );
  • The server recieves the sendMsgTo event and uses the to parameter to send the private message:
    socket.on( 'sendMsgTo', function( msgObj ){
    		
    		socket.to( msgObj.to ).emit( 'privateMsg', {msg:msgObj.msg, from:socket.id} );
    	});
  • UserB now gets the privateMsg event, containing our message

Now, I've named the send and receive message event differently for clarification, but you can use the same name if you wish.

The only reason I'd have a chat room for private chat between two users is if you wanted to keep a chat history (e.g. one of the users refreshes their page and they're not coming back to a blank page), or it's possible that another user might join them later.

Also keep in mind that the socket.id changes when users refresh/reconnect, so you'll have to have an event to get other users to update their values when this happens.

Vishruth

I am facing some issues,
I have posted my question here

http://stackoverflow.com/questions/42906574/azure-web-node-js

Hi

I'm making a game using socket.io
The problem I'm facing is that when the first client joins the game, he/she can't do anything until the second client comes. Now I've simply applied an if condition stating that when my lists of clients == 2 only then can you make a move. But when i do this the first player can't make any moves at all.
Could you please help out?

Damian Connolly

Hi,
This is more of a logic or architecture question than something specific to socket.io. All online games have to deal with the same issue that you have. What you do in your particular case depends on the experience that you want to give.

The way we tackle it on Microgolf is that when you click to play a game, on the server you're added into a queue. On the client, we play an animation to show that we're searching for an opponent. At this point, the only thing that they can do is leave the queue (bascially quitting the screen).

It's only when we have 2 players on the server that we create the game, add the players to it, and notify them that a game was found. At this point, on the client, we transition into the game screen.

Waiting queues, or lobbies, are pretty common in dealing with this sort of issue, and relatively easy to set up. It's dealing with all the timing and delays that's the killer (like someone leaving the queue after the game has been created on the server, but before they've received it on the client :D)

In your particular case, it's normal that the player can't make any moves while waiting on an opponent to arrive. All you need to do is show them that they're waiting with a small animation or something similar.

Vivek

Hi,
I'm trying to implement a private chat between two clients. But difference is they need to login to send a message, that i have taken care of.
But i am confused to how to send msg to a client from another client if this client is offline. In this case i don't have socket.id of this user.

Damian Connolly

Hi Vivek,
If you want to do offline message, then you're going to need a DB. You can technically store them in memory, but you'd lose any messages if you're in a multi-server environment, or restart your server. A simple approach:

  • As your users have to login to send a message, they must have some form of unique identifier - this is going to be your ID for their messages object in the DB
  • UserA sends UserB a message. UserB is offline, so the message needs to get saved
  • UserA will need to know the unique identifier of UserB, in order to save a message for him. Normally you'd either stock this on UserA, in their friends object, or send it with every message. Note, this is not the socket.id for UserB, as that changes every time they connect
  • We do a search for UserB's messages object. If it exists, great, if not, then we create it. This object is very basic. If you're using MongoDB, then it's be something like { _id:"UniqueIDForUserB", messages:[] }
  • We create an object for the message. Typically this will be the same object that you send if they were online chatting in real-time, but you might want to add extra info
  • We insert the object into UserB's messages object. As they can get multiple messages while offline, this is obviously an Array
  • The next time UserB comes online, he queries his messages object, and if there's anything in the array, we dispatch it on and clear the array (unless you want to keep a history)

Let me know if any of that doesn't make sense. You can use any DB that you like for this. Personally, I'm more familiar with MongoDB, and as a JavaScript dev, it's super easy to get up and running on it. There aren't very many shared hosting with Mongo included however, so it'll probably mean a dedicated server.

Hi, I am Norbert

Thanks for a great explanation on IO. Kindly advise what could be the best approach, if i want to send messages to a group of my followers only. something similar to tweeter, where you get to see tweet of people you follow only. Thanks

Damian Connolly

Hi Norbert,
Socket.io is only really for people that are connected right now, so it would depend on your application:

  • If you only want to notify connected users, then it's as simple as having everyone in the same room (as each user has a room, they can just join yours) and dispatching a message to it
  • If you want something more like Twitter where users post updates and followers can read them when they connect later, then you're saving your messages to a DB. How you actually show your messages differs. A simple approach is just to pull all messages from people you follow after X timestamp. Twitter uses somewhat more complex algorithms as they show messages that you could be interested in, etc. The principle is the same however.
Fezekile Plaatyi

You touched every part that is needed by Newbie to Socket.io like me. Thanks a lot. I am gonna create an App from this.

General

Best tutorial i ever seen about socket

rupesh kumar

https://gist.github.com/rupesh2017/1551c56e39759b412624f0202073b931

https://gist.github.com/rupesh2017/9590be8621b2899caed70a534a00b1f1

Sending a message to another user - connected dictionary on our namespace?

var otherSocket = sio.sockets.connected[userID];

please explain this?

i tried running in console

var socket = io.connect(location.protocol + '//' + document.domain + ':' + location.port);
socket.id  // it worked

i tried

var otherSocket = socket.sockets.connected[userID];
socket.sockets.connected?? error

does userID here is socket.id

Damian Connolly

Hi Rupesh,
If I understand you correctly, you're having a problem with sending a message to another user?

It looks like the issue is that you're trying to run this particular code on the client, rather than the server. Any time you see socket you can assume it's server code, while clientSocket points to client code.

Only the server has a list of connected sockets, held in an Object with the socket's ID as the key. To break the flow into steps:

  • User1 sends an event to the server saying that they'd like to send a message to User2
  • On the server, we find the socket for User2, using it's ID as the key, from the connected Object
  • Once we have the socket, the server forwards User1's message to User2
  • User2 receives the message event

For User1 to send a message to User2, they need to know User2's ID (or any other uniquely identifying feature, such as a username that you're stocking).

How they get this depends largely on your preference, but a simple method is to send a "user joined" event when a socket connects to a room, and to send the ID with that.

Hi, Am david

Am trying to build a chat app, where user can message themselves privately, but am confuse on either to use the approach of joining a room or storing the socket. because i will like to keep chat history and also am using mysql database. please advice me. if am to use join room approach , how can i dynamically create and subscribe the two user to the room and still keep chat history for them. thanks.

Damian Connolly

Hi David,
I'm not 100% sure I know what you mean when you say "storing the socket". Because the ID of the socket is different every time the socket connects, in order to keep a history, you'll need to develop that functionality yourself.

I'd probably do something like the following:

  • Each user in your chat app has a unique key to identify them in your DB. This can be their nickname, email, an app-specific ID, whatever you want. Your user object holds their nickname, avatar, friends, chat rooms (keys) etc. Something like
    {
    	"id": "User2320203",
    	"nickname": "Damian",
    	"email": "foo@email.com",
    	"password": "sadgj98g2t{agsaA_AGKauasdgu2%&",
    	"friends":[
    		"User2030020",
    		"User1028238"
    	],
    	"rooms":[
    		"Room203082382",
    		"Room191834803"
    	]
    }
  • When they connect to the app, one of the first events they send is an Auth event. How you do your authentication is up to you (JSON web tokens, password, whatever), but it's just so that we can associate the unique socket ID with the user, and mark them as online
  • You also have the concept of chat rooms. This is a unique key (e.g. ChatRoom29837275762), a list of the users subscribed, and any previous chat history
  • When a user connects, we can load any rooms they have stored (or optionally only load them when they "enter" them, depending on how your app works). Everyone in the room can get a notification that you're online
  • When users join a chat room for the first time, we store the rooms key on their user object, and send them the chat history (you can store this client-side so they don't get a massive dump every time)
  • To send a message to the chat room, you simply add the room key. Once on the server, you can forward the message to everyone in the room, and store it in the DB for history
  • A room can have 2 or 200 people in it - think along the lines of a WhatsApp group - so whether it's a group chat or a private chat is irrelevant to the code. To chat with someone, create the room, then add it to both users' object

Submit a comment

* indicates required