'Socket.io event works randomly

What I'm trying to do is to emit a event based on the progress of my jobs. It's working in the Gateway(proxy) side, the logs appear, etc, but when I'm consuming the event on the front-end, sometimes it works, sometimes not, and it throws 'ping timeout' error in the console. If I restart the nodejs service a few times it works. I'm open to ideas of alternative ways to implement this feature.

SocketController

export default class SocketController {
  socket: any;
  interval: any;
  instance: any;
  queue: any;

  constructor(server) {
    // Creating Websocket connection
    this.instance = new Server(server, {
      cors: { origin: process.env.FRONTEND_URL },
      path: "/socket.io/"
    });
    this.socket = null;
    this.queue = null;

    this.instance.on("connection", (socket) => {
      let connectedUsersCount =
        Object.keys(this.instance.sockets.sockets).length + 1;
      let oneUserLeft = connectedUsersCount - 1;

      console.log("New client connected ", connectedUsersCount);

      // Assign socket to the class
      this.socket = this.socket == null ? socket : this.socket;

      /*
            if (this.interval) {
              clearInterval(this.interval);
            }
            */

      // initialize Queue
      this.queue = this.queue === null ? new QueueService(socket) : this.queue;

      socket.on("disconnect", () => {
        console.log("Client disconnected ", oneUserLeft);
        // clearInterval(this.interval);
      });
    });
  }

QueueService

export default class QueueService {
  channels: any;
  socket: any;

  constructor(socket: any) {
    this.channels = ["integrationProgress", "news"];
    this.socket = socket;

    integrationQueueEvents.on("progress", (job: any) => {
      console.log("Job Progressing", job);
      this.socket.emit("integrationProgress", { status: true, data: job.data })
    });

    integrationQueueEvents.on("active", ({ jobId }) => {
      console.log(`Job ${jobId} is now active`);
    });

    integrationQueueEvents.on("completed", ({ jobId, returnvalue }) => {
      console.log(`${jobId} has completed and returned ${returnvalue}`);
      this.socket.emit("integrationComplete", {
        status: true,
        message: returnvalue
      });
    });

    integrationQueueEvents.on("failed", ({ jobId, failedReason }) => {
      console.log(`${jobId} has failed with reason ${failedReason}`);
      this.socket.emit("integrationProgress", {
        status: false,
        message: failedReason
      });
    });
  }
}

Front-End

const socket = io(process.env.GATEWAY_URL, {
  path: "/socket.io/"
});

socket.on("connect_error", (err) => {
  console.log(`connect_error due to ${err.message}`);
  socket.connect();
});

socket.on("disconnect", (socket) => {
  console.log(socket);
  console.log("Client disconnected ");
});

socket.on("connect", (socket) => {
  console.log("Client Connected ");
  console.log(socket);
});

socket.on("integrationProgress", async (socket) => {
  try {
    console.log(`Progress: ${socket.data}`);
    updateJob(socket.data);
  } catch (err) {
    console.log(err);
  }
});


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source