DEV Community

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

Posted on Edited 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!

Top comments (8)

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

Collapse
 
duanegabriel profile image
Duane Gabriel

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

Collapse
 
mthew profile image
M_thew

Heeey bro, thanks, your article is very helpfull

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
 
jawadch profile image
jawad-ch

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

Collapse
 
huynhquanhht profile image
Quan Huynh

Thanks. Your article is very helpful.