0

I am using this code for socket cluster.

HTML:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Worker Socket Connection</title>
  </head>
  <body>
        <button id="connect_socket" onclick="connectSocket()" type="submit">
          connect
        </button>
        <br>
        <br>
        <textarea cols="50" rows="15" id="message"></textarea>

    </div>

    <!-- make sure you're using the same socket version in server and client -->
    <script src="https://cdn.socket.io/4.6.0/socket.io.min.js" integrity="sha384-c79GN5VsunZvi+Q/WObgk2in0CbZsHnjEqvFxC5DxHn9lTfNce2WW6h2pH6u/kF+" crossorigin="anonymous"></script>
    <script src="main.js"></script>
  </body>
</html>

Client side code:

var log = (mgs, ctx) => {
    ctx = ctx ?? '===';
    let messageBox = document.getElementById('message')
    messageBox.innerHTML += `${ctx}: ${mgs}` + "\n"
}

var connectSocket = () => {
    const socket = io({
        extraHeaders: {
            "my-token": "token-goes-here"
        },
    });
    // client-side
    socket.on("connect", () => {
        log(socket.id, 'socket_id');
        log(socket.connected, 'connection_status');

        socket.on("server_data", (arg) => {
            log(arg, 'server_data');
        });
    });

    socket.on("connection_error", (err) => {
        log('error', err);
    })

    socket.on("disconnect", (reason) => {
        log('socket disconnected', reason)
        log(socket.id, 'socket_id'); // undefined
        log(socket.connected, 'connection_status'); // false
    });
    socket.on("connect_error", () => {
        log('connect_error & reconnect');
        socket.connect();
    });

};

Server side code:

import cluster from "cluster"
import express from "express"
import cors from "cors"
import path from "path"
import os from "os"
import { Server } from "socket.io"
import { setupMaster, setupWorker } from "@socket.io/sticky"
import { createAdapter, setupPrimary } from "@socket.io/cluster-adapter"
let numCPUs = os.cpus().length
const __dirname = path.resolve(path.dirname(''));

const PORT = 3000;
const HOST = '0.0.0.0';

if (cluster.isPrimary) {
  console.log(`Master ${process.pid} is running`);

  const app = express()
  // setup sticky sessions
  setupMaster(app, {
    loadBalancingMethod: "least-connection",
  });

  // setup connections between the workers
  setupPrimary();
  // needed for packets containing buffers (you can ignore it if you only send plaintext objects)
  // Node.js > 16.0.0
  cluster.setupMaster({
    serialization: "advanced",
  });

  // app.listen(+PORT, HOST, () => { })

  for (let i = 0; i < numCPUs; i++) {
    cluster.fork();
  }

  cluster.on("exit", (worker) => {
    console.log(`Worker ${worker.process.pid} died`);
    // cluster.fork();
  });
} else {
  console.log(`Worker ${process.pid} started`);
  const app = express();
  app.use(express.json());
  app.use(express.urlencoded({ extended: true }));

  app.use(cors());
  app.use(function (req, res, next) {
    res.header("Access-Control-Allow-Origin", "*");
    next();
  });

  app.use(express.static(__dirname + "/static/"));

  // const httpServer = http.createServer();
  console.log(`'HTTP server started' on port ${PORT}`);
  const server = app.listen(+PORT, HOST, () => { });

  app.get('/', async (req, res) => {
    res.sendFile(__dirname + '/static/index.html');
  });

  const io = new Server(server,{
    cors: {
      origin: "*",
      methods: ["GET", "POST"]
    },
    maxHttpBufferSize: 1e10,
    pingInterval: 10000, // 10 seconds
    pingTimeout: 60000, // 60 seconds
  })

  // use the cluster adapter
  io.adapter(createAdapter());

  // setup connection with the primary process
  setupWorker(io);

  io.on("connection", function (socket) {
    console.log("Made socket connection");
    console.log(socket.handshake.headers);

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

But with this code I couldn't connect the socket. It always show the transport_error or ws://localhost:3000/socket.io/ failed. If I use "transport": ["websocket"]. Then it connects perfectly but I couldn't set the headers. I need to send headers too from client to server. Please help me how to solve and work with it. Reference code: https://socket.io/docs/v4/cluster-adapter/.

I will really appreciate if I get the solution. Thanking you in advance.

0 Answers0