Search code examples
node.jssocket.io

socket.io setup unsuccessful in nodejs


Problem:

Setup of socket.io to backend node js server unsuccessful. Attempts to connect from both postman and my frontend react app were both unsuccessful.

frontend terminal error message:

App.js:6 
 
 GET https://project001db-11.onrender.com/socket.io/?EIO=4&transport=polling&t=P1GAxrA 404 (Not Found)
create  @   polling.js:298
Request @   polling.js:237
request @   polling.js:190
doPoll  @   polling.js:215
poll    @   polling.js:96
doOpen  @   polling.js:56
open    @   transport.js:46
open    @   socket.js:170
Socket  @   socket.js:111
open    @   manager.js:108
Manager @   manager.js:38
lookup  @   index.js:29
./src/App.js    @   App.js:6
options.factory @   react refresh:6
__webpack_require__ @   bootstrap:22
fn  @   hot module replacement:61
./src/index.js  @   TextDecoratorBgIMG.js:21
options.factory @   react refresh:6
__webpack_require__ @   bootstrap:22
(anonymous) @   startup:7
(anonymous)

postman error message:

Error: Unexpected server response: 404
Handshake Details
Request URL: https://project001db-11.onrender.com/socket.io/?EIO=4&transport=websocket
Request Method: GET
Request Headers
Sec-WebSocket-Version: 13
Sec-WebSocket-Key: V9DaaiwnspTbd2OaBv42BQ==
Connection: Upgrade
Upgrade: websocket
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
Host: project001db-11.onrender.com

setup background

backend: node.js, express.js, socket.io, restapi

hosting server: render webservice

Server side code

const supabase = require("./configdb.js");
const express = require("express");

//socket.io
const { Server } = require("socket.io");
const { createServer } = require("http");

const app = express();
const cors = require("cors");
const port = 3000;

app.use(cors());

app.use(express.json());

//set up socket connection to record online user
const httpServer = createServer(app);
const io = new Server(httpServer, {
  cors: {
    origin: "https://project001db-11.onrender.com",
  },
});

let onlineUser = {};

io.on("connection", (socket) => {
  socket.on("userConnected", (user) => {
    onlineUser[socket.id] = user;
    io.emit("updateUserList", Object.values(onlineUsers));
  });

  socket.on("disconnect"),
    () => {
      delete onlineUsers[socket.id];
      io.emit("updateUserList", Object.values(onlineUsers));
    };
});

// Set port, listen for requests.
app.listen(port, () => {
  console.log(`Server is running on port ${port}.`);
});

// Add routes routes.
require("./routes/chat.routes.js")(express, app);

Client side

import "./App.css";
import Chatroom from "./Chatroom";
import { io } from "socket.io-client";
import { useEffect } from "react";

const socket = io("https://project001db-11.onrender.com");

function App() {
  useEffect(() => {
    socket.emit("userConnected", { username: "JohnDoe" });

    socket.on("updateUserList", (users) => {
      console.log("Updated user list:", users);
    });

    return () => {
      socket.disconnect();
    };
  }, []);

  return <Chatroom />;
}

export default App;

I tried to follow the socket.io document to set up the backend server and was expecting the connection to be set up successfully so that I can get a list of online users stored in the backend memory.


Solution

  • There are a few issues with your code. Here are the corrections:

    Typo in variable name 'onlineUsers'. You declared the object as onlineUser, but you reference it as onlineUsers in multiple places.

    Syntax error in the disconnect event handler: The arrow function is incorrectly placed. It should be inside the socket.on function call.

    Start the HTTP server using httpServer.listen: The server should start listening using httpServer.listen instead of app.listen since httpServer is created with createServer(app).

    Here's the corrected code:

    const supabase = require("./configdb.js");
    const express = require("express");
    const { Server } = require("socket.io");
    const { createServer } = require("http");
    
    const app = express();
    const cors = require("cors");
    const port = 3001;
    app.use(cors());
    app.use(express.json());
    const httpServer = createServer(app);
    const io = new Server(httpServer, {
        cors: {
            origin: "*", // Replace with your client URL
            methods: ["GET", "POST"],
            credentials: true,
        },
    });
    
    let onlineUsers = {};
    
    io.on("connection", (socket) => {
        socket.on("userConnected", (user) => {
            onlineUsers[socket.id] = user;
            console.log("User connected:", user);
            io.emit("updateUserList", Object.values(onlineUsers));
        });
    
        socket.on("disconnect", () => {
            delete onlineUsers[socket.id];
            io.emit("updateUserList", Object.values(onlineUsers));
        });
    });
    
    // Set port, listen for requests.
    httpServer.listen(port, () => {
        console.log(`Server is running on port ${port}.`);
    });
    
    // Add routes routes.
    require("./routes/chat.routes.js")(express, app);
    

    Verify your connection url in the client side app. Try running it on the localhost instead of the deployed url. Makesure the deployed url is working properly.