DEV Community

Cover image for How to uncouples emit events from connection event into socket.io and express
Marcos Henrique
Marcos Henrique

Posted on • Updated on

How to uncouples emit events from connection event into socket.io and express

Preface 👓

I've worked in a project with node.js, express and websockets, In a part of the project I realized the need to uncouples the sending of messages to the websocket, since I would need to do this in a place where there was no instance of it, in my case it was on a specific route in the middle of the business rule logic.

I would need to send the return in real time of each stage of this processing, and among all the alternatives, such as passing the socket instance as a route by route parameter (in my project I have unification of the routes by prefix) and having to refactor a lot of the that I had already done, I found this way that I present to you

Socket.io 📨

Socket.IO is a JavaScript library for realtime web applications. It enables realtime, bi-directional communication between web clients and servers.

Socket.IO is NOT a WebSocket implementation.

Although Socket.IO indeed uses WebSocket as a transport when possible, it adds some metadata to each packet: the packet type, the namespace and the packet id when a message acknowledgement is needed.

That is why a WebSocket client will not be able to successfully connect to a Socket.IO server, and a Socket.IO client will not be able to connect to a WebSocket server either.

You can see more about socket.io here.

Socket Service Class ✨

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

class SocketService {
   constructor(server) {
     this.io = socketIo(server);
     this.io.on('connection', socket => {
       console.log('user connected')
   });
 } 

  emiter(event, body) {
    if(body)
      this.io.emit(event, body);
  }
}

module.exports = SocketService;

Enter fullscreen mode Exit fullscreen mode

Implementation in app.js 👾

In the main of my application, there I was put the instance of Socket Service as a singleton into express app.

With that I was able to use it on other routes without having to modify anything on them

const express = require('express');
const app = express();
const server = require('http').Server(app);

app.use(express.json());
app.use(`/`, require('./routes'));

server.listen(3001, function () {
  console.debug(`listening on port 3001`);
});

 app.set("socketService", new SocketService(server));
Enter fullscreen mode Exit fullscreen mode

Using in the route controller or anywhere you want 🛣

//using req to access app that I had defined before
req.app.get("socketService").emiter('message', req.body);

//anywhere with access to app:
app.get("socketService").emiter('message', req.body);
Enter fullscreen mode Exit fullscreen mode

that's all, i hope this can help you in your projects!

Latest comments (8)

Collapse
 
gantushig77 profile image
Gantushig77

You solved my problem and saved my project. Thank you very much. I appreciate your work. Please keep doing your amazing work. 👏👏👏

Collapse
 
mthew profile image
M_thew

Heeey bro, thanks, your article is very helpfull

Collapse
 
huynhquanhht profile image
Quan Huynh

Thanks. Your article is very helpful.

Collapse
 
jawadch profile image
jawad-ch

@wakeupmh can you please show us how to use this with client side

Collapse
 
duanegabriel profile image
Duane Gabriel

Brother, you're article in a few words solved my problem, thank you.
Cheers from Brazil.

Collapse
 
thebrown profile image
Saleumsack

Thank you so much, Finally I found the way to use Socket IO in the express route

Collapse
 
wakeupmh profile image
Marcos Henrique • Edited

I'm happy to have helped 🤘

Collapse
 
sharpex profile image
sharpex

This is great i have searched for it for two days tried all stackoverflow solutions none was working....Thanks