I'm encountering an issue with WebSocket connections in my Node.js application using Socket.IO. When attempting to establish a WebSocket connection to my server at localhost:3000, I consistently receive the following error:
WebSocket connection to 'ws://localhost:3000/socket.io/?EIO=4&transport=websocket&sid=umeoel1BdvaFWg_VAAAM' failed:
This error occurs only once at the very beginning when the client attempts to connect to the server. After this initial error, the WebSocket connection is established successfully, and I don't encounter any further errors.This my code:
backend.js:(after that there are some app.get and app.posts for e.g(/login, /logout etc.)
const dotenv = require('dotenv');
const express = require('express');
const session = require('express-session');
const pgSession = require('connect-pg-simple')(session);
const { createServer } = require('node:http');
const { join } = require('node:path');
const fs = require('fs');
const { Pool } = require('pg');
const bodyParser = require('body-parser');
const bcrypt = require('bcrypt');
// Initialize Express application
const app = express();
// Define saltRounds for bcrypt hashing
const saltRounds = 10;
// Create an HTTP server using Express
const server = createServer(app);
// Initialize Socket.io for real-time communication
const io = require('socket.io')(server, {
cors: {
origin: "http://localhost:3000",
methods: ["GET", "POST"],
transports: ['websocket', 'polling'],
allowedHeaders: ['Access-Control-Allow-Origin'],
credentials: false
},
allowEIO3: true,
cookie: {
name: "io",
path: "/",
httpOnly: true,
sameSite: "lax"
}
});
io.attach(server);
// Listen for connections on port 3000
server.listen(3000, () => {
console.log('server running at http://localhost:3000');
});
//Create a PostgreSQL connection pool
const dbConfig = JSON.parse(fs.readFileSync('db_config.json'));
// Load environment variables from .env file
dotenv.config();
const pool = new Pool(dbConfig);
//Create new session
const sessionMiddleware = session({
store: new pgSession({
pool : pool, // Connection pool
tableName : 'session',
createTableIfMissing: true, // Use another table-name than the default "session" one
// Insert connect-pg-simple options here
}),
secret: process.env.SESSION_SECRET,
resave: false,
saveUninitialized: true,
cookie: { maxAge: 30 * 24 * 60 * 60 * 1000 }, // 30 days
name: 'sessionid',
// Insert express-session options here
});
// Make `pool` available to other parts of the application as needed
module.exports = pool;
// Store session IDs
const accounts = {};
//
//APP.USE
//
//Create new session
app.use(sessionMiddleware);
// Set up body-parser middleware to parse request bodies
app.use(bodyParser.urlencoded({ extended: true }));
// Serve static files from the 'public' directory
app.use(express.static('public'));
//Share session context with Socket.IO
io.engine.use(sessionMiddleware);
io.engine.on("connection_error", (err) => {
console.log(err.req); // the request object
console.log(err.code); // the error code, for example 1
console.log(err.message); // the error message, for example "Session ID unknown"
console.log(err.context); // some additional error context
});
//
//CONNECTION
//
// Handle socket connection event
io.on('connection', (socket) => {
console.log('a user connected');
// Add the connected user to the accounts object
accounts[socket.id] = {};
// Emit 'updtplayer' event to update clients with current player information
io.emit('updtplayer', accounts);
console.log(accounts);
// Handle socket disconnection event
socket.on('disconnect', () => {
console.log('a user disconnected');
// Remove the disconnected user from the accounts object
delete accounts[socket.id];
console.log(accounts);
});
});
//
//APP.GET
//
//Serve index.html when root URL is accessed
app.get('/',(req,res, next)=>{
res.sendFile(join(__dirname + '/public/index.html'))
});
And (a part of) my frontend js:
const canvas = document.querySelector('canvas')
const c = canvas.getContext('2d')
const socket = io();
canvas.width = 600
canvas.height = 700
c.fillStyle = "#ff9966"
c.fillRect(0, 0, 200, 300)
console.log("I'm working");
socket.on('updtplayer', (accounts) =>{
console.log(accounts);
})
(a part of) index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Big Game</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"> <!--This imports icons-->
<link rel="stylesheet" href="index.css">
<link rel="stylesheet" href="customElements.css">
</head>
<body>
<!--Include Canvas with id = myCanvas-->
<canvas id="myCanvas" width="600" height="800"></canvas>
<!--Import AJAX, Socket.io and index.js-->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.socket.io/4.7.4/socket.io.min.js"></script>
<script src="index.js"></script>
<script src="customElements.js"></script>
</body>
</html>
I'm using Node.js with Express and Socket.IO for real-time communication. The client-side code for establishing the WebSocket connection is straightforward and doesn't appear to be the cause of the issue. I've verified that the server is running and listening on the correct port (localhost:3000). I'm not using any proxy or firewall settings that could interfere with WebSocket connections. The error occurs consistently only once at the beginning, and subsequent WebSocket connections are established successfully without errors.