Skip to content

Instantly share code, notes, and snippets.

@luciopaiva
Last active January 6, 2024 06:20
Show Gist options
  • Star 99 You must be signed in to star a gist
  • Fork 25 You must be signed in to fork a gist
  • Save luciopaiva/e6f60bd6e156714f0c5505c2be8e06d8 to your computer and use it in GitHub Desktop.
Save luciopaiva/e6f60bd6e156714f0c5505c2be8e06d8 to your computer and use it in GitHub Desktop.
Full socket.io client and server example

Full socket.io client and server example

Last updated: 2021-02-21, tested with socket.io v3.1.1

This is the simplest implementation you will find for a client/server WebSockets architecture using socket.io.

To see a full explanation, read my answer on SO here: https://stackoverflow.com/a/24232050/778272.

If you're looking for examples using frameworks, check these links:

How to run

Create a folder, run npm init -f on it and paste both server.js and client.js there (see files below). Needless to say, you must have Node.js installed on your system.

Install the required libraries:

npm install socket.io@3.1.1
npm install socket.io-client@3.1.1

Run the server:

node server

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

node client
const
io = require("socket.io-client"),
ioClient = io.connect("http://localhost:8000");
ioClient.on("seq-num", (msg) => console.info(msg));
const
{Server} = require("socket.io"),
server = new Server(8000);
let
sequenceNumberByClient = new Map();
// event fired every time a new client connects:
server.on("connection", (socket) => {
console.info(`Client connected [id=${socket.id}]`);
// initialize this client's sequence number
sequenceNumberByClient.set(socket, 1);
// when socket disconnects, remove it from the list:
socket.on("disconnect", () => {
sequenceNumberByClient.delete(socket);
console.info(`Client gone [id=${socket.id}]`);
});
});
// sends each client its current sequence number
setInterval(() => {
for (const [client, sequenceNumber] of sequenceNumberByClient.entries()) {
client.emit("seq-num", sequenceNumber);
sequenceNumberByClient.set(client, sequenceNumber + 1);
}
}, 1000);
@skibinalexander
Copy link

skibinalexander commented Oct 16, 2019

I use this practice:

var app = require('express')();
var http = require('http').createServer(app);
var io = require('socket.io')(http);

app.get('/', function(req, res){
    res.send('Hello World!');
});

io.on('connection', function(socket){
  socket.on('chat message', function(msg){
    console.log('message: ' + msg);
  });
});

http.listen(3086, '1**92.168.8.1:3086**', function(){
  console.log('listening on *:3086');
});

@skibinalexander
Copy link

skibinalexander commented Oct 16, 2019

And in your code , i need use 192.168.8.1:308 address

@luciopaiva
Copy link
Author

(Edited your comment above for proper syntax highlighting)

I see, so you're using Express. Check socket.io docs, they have an example on how to make it work with Express:
https://socket.io/docs/#Using-with-Express

@luciopaiva
Copy link
Author

@skibinalexander I forgot that I have an example using Express as well, so that may help you:
https://github.com/luciopaiva/socketio-with-express

Matter of fact, I also happen to have one for Restify:
https://github.com/luciopaiva/socketio-with-restify

@atmimran
Copy link

atmimran commented Feb 8, 2020

Is it work in with PhoneGap?

@NervenCid
Copy link

NervenCid commented Feb 10, 2020

Hello i find you tread on internet:

I looking for use a websocket from the controller but i can't access io object from the controller:

Her is my code:

index.js:

//Importamos la app
const app = require('./app');

const socketIO = require('socket.io');

//Con el modulo 'dotenv' importamos las variables de entorno
//contenidas dentro del archivo '.env'
//Se recomienda correr este proyecto con permisos de administrador
require('dotenv').config();

//Importamos la conexion a la base de datos dentro de 'database.js'
require('./database/database');

//Esta funcion ejecuta el servidor
async function main(){


    //Obtenemos el puerto
    const PORT = app.get('port');  

    //Escuchamos el servidor en puerto y con '0.0.0.0' podemos acceder publicamente
    server = await app.listen(PORT, '0.0.0.0');

    
    const io=socketIO.listen(server);

    //console.log('io index: ', io)

    /*
    io.on('connection', function(){
        console.log('Socket Conectado');
        io.emit('Prueba', 'Hola soy el servidor'.toString());
    });
    */
    
    
    //Mostramos por consola
    console.log('Servidor ejecutandose en el puerto: ', PORT);

> };

main();

@luciopaiva
Copy link
Author

Is it work in with PhoneGap?

Not sure, never had any experience with PhoneGap. Please let us know if you find out!

@luciopaiva
Copy link
Author

@NervenCid I suggest you try to reproduce the issue with a smaller script first. There's too much unrelated logic in the code you pasted and it's difficult to spot what may be wrong.

@NervenCid
Copy link

@luciopaiva Done, comment updated

@ttfreeman
Copy link

Unfortunately, it doesn't work for me. I get this error:
image

@luciopaiva
Copy link
Author

I have just updated the example to work with the latest socket.io version (3.1.1). For those still having problems, give it a try now. I also changed the npm command to make sure future socket.io versions won't break this example.

@Amine27
Copy link

Amine27 commented Apr 16, 2021

Thanks for the gist.
You can also use room concept of socket.io, instead of a global variables, to store users.

@luciopaiva
Copy link
Author

Thanks for the gist.
You can also use room concept of socket.io, instead of a global variables, to store users.

If one is only keeping track of users, using rooms seems like a nice suggestion indeed.

In the example above, however, I also keep a state for each user (their current sequence number). I did this to illustrate how one would store data for each user.

Regarding your mention of the use of global variables: in my example, the Map variable is only visible within the module. It could also be easily turned into an instance member by encapsulating the login within a class (which I would probably do if the logic got more involved).

@Amine27
Copy link

Amine27 commented Apr 16, 2021

I would like to mention that the room is also useful when you have one user connected from multiple devices, in your example, you have to do more tweaks in this situation. Moreover, the room will delete users as soon as they disconnect, so you don't have to track their status.

@Pic2490
Copy link

Pic2490 commented Feb 26, 2022

Exactly what I needed, you're the man

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment