Encountered an issue when trying to proxy to the Node.js/Express Socket.IO server with Next.js

I'm currently facing an issue with establishing a connection between my Next.js/React client and my Express/Socket.io backend (not running as a Next.js custom server). When I attempt to proxy regular HTTP requests using rewrites in the next.config.js file, everything works smoothly. However, when trying to connect to the server via websockets (using Socket.io), I encounter this error message in the terminal:

Failed to proxy http://localhost:8000/socket.io?EIO=4&transport=websocket Error: socket hang up
    at connResetException (node:internal/errors:705:14)
    at Socket.socketOnEnd (node:_http_client:518:23)
    at Socket.emit (node:events:525:35)
    at endReadableNT (node:internal/streams/readable:1358:12)
    at processTicksAndRejections (node:internal/process/task_queues:83:21) {
  code: 'ECONNRESET'
}

Here's the content of my app.js located at ./backend/app.js:

require("dotenv").config();
const express = require("express");
const cookies = require("cookie-parser");
const cors = require("cors");
const http = require("http");
const { Server } = require("socket.io");
const connect = require("./models/database");

const app = express();
const server = http.createServer(app);
const io = new Server(server);

// Connecting to MongoDB database
connect();

// Setting up middleware
app.use(express.json());
app.use(cookies());
app.use(cors());
app.use(require("./middleware/logger"));

// Defining API routes
app.use("/v1", require("./api/v1"));

// Setting up websocket entry point
io.on("connection", require("./api/socket.io-v1"));

// Starting the server
server.listen(process.env.PORT, () => {
  console.log(`[STATUS]: Server started at port ${process.env.PORT}`);
});

This is my configuration in next.config.js located at ./frontend/next.config.js:

/** @type {import('next').NextConfig} */

module.exports = () => {
  const rewrites = () => {
    return [
      {
        source: "/v1/:path*",
        destination: "http://localhost:8000/v1/:path*",
      },
      {
        source: "/socket.io/:path*",
        destination: "http://localhost:8000/socket.io/:path*",
      },
    ];
  };

  return {
    rewrites,
  };
};

Finally, the instance where socket is defined within one of the component files (outside of the component itself):

const socket = io("http://localhost:3000", { transports : ['websocket'] });

If anyone could provide guidance on how to properly proxy the socket connection to the external Express server since proxying requests has worked fine while using create-react-app, I would greatly appreciate it. Thank you.

Answer №1

I encountered a similar issue.

http://localhost:8000/socket.io?EIO=4&transport

The problem persisted when using curl:

curl "http://localhost:3010/socket.io?EIO=4&transport=polling&t=OHwXDb-"

However, it only worked with a forward slash:

curl "http://localhost:3010/socket.io/?EIO=4&transport=polling&t=OHwXDb-"

In Nextjs, the destination would always lose the slash. By removing :path*, I was able to get it working:

{
  source: '/socket.io',
  destination: `${process.env.NEST_API}/socket.io/`,
 }

Alternatively, you can utilize path:

 {
      source: '/socket.io/events/:path*',
      destination: `${process.env.NEST_API}/socket.io/events/:path*`,
     }

This method will work with :path* included.

Answer №2

Although I am still hopeful for a response to this inquiry, I have taken matters into my own hands by manually adjusting the socket.io connection URL to match the precise server address:

const socket = io("http://localhost:8000", { transports : ['websocket'] });

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Unexpected Token E encountered in the Twitter stream.on function

I'm currently in the process of setting up a search button on my web application that will pull all Twitter tweets related to the search input using the streaming API. Below is my client-side code: <form class="navbar-form navbar-left" role="sear ...

Navigating files using NodeJS and ExpressJS

Can NodeJS (or ExpressJS) facilitate the following task? Although I appreciate the flexibility that routing provides, I find the configuration process quite cumbersome. (I don't consider myself an expert in Express) For instance, imagine an applicat ...

The simple passport.js sign-up feature is not successful as it mistakenly believes that the username is already in

Currently, I am working on setting up a basic signup feature for my Node + Express + Sequelize application using passport.js. The database is empty at the moment, and I am utilizing the passport-local strategy to extract the user's email and password ...

Error encountered when initializing OGM on Neo4j GraphQL Express Server due to unhandled promise rejection

Currently, I am integrating Express with Neo4j GraphQL. An exception has been thrown without specific line indications in my code. node:internal/process/promises:289 triggerUncaughtException(err, true /* fromPromise */); ^ [Unhand ...

Extend the express request object with Typescript and then export the modified object

Seeking to enhance the Request object from express with custom fields using typescript. Based on this particular source, I created a file named @types/express/index.d.ts containing the following code : import { MyClass } from "../../src/MyClass" ...

What is the best way to save SQL statements on my API server?

I am in the process of developing an API server that requires SQL queries with approximately 20-40 lines each. To keep things simple, I have opted to use NodeJS, express, body-parser, and a database connector for this server. In previous environments, I ...

When React object state remains unchanged, the page does not update automatically

i have a state object with checkboxes: const [checkboxarray_final, setCheckboxarray_final] = useState({ 2: ",4,,5,", 9: ",1,", }); i'm working on enabling check/uncheck functionality for multiple checkboxes: these are ...

Why is the source alignment different when using Next.js compared to WordPress?

As a newcomer to NextJS, I am eager to learn more about it in order to develop websites that are easily discoverable by Google's search engine algorithms and have strong SEO performance. Wordpress is renowned for its SEO capabilities as it neatly outp ...

Having trouble initiating the server using npm start

Just starting out with nodeJs: I have created a server.js file and installed nodejs. However, when I try to run "npm start", I encounter the following errors. C:\Users\server\server.js:43 if (!(req.headers &amp;& req.headers. ...

Issues with Paypal react and Next JS buttons failing to reflect changes in shopping cart quantities

There seems to be an issue with the React PayPal Buttons integration. Despite updating the quantity of products in the cart, the changes are not being reflected in certain components like createOrder and onApprove within the PaypalButtons props. As a resul ...

Tips for transforming the <img> element into a Nextjs <Image> component

I have been working with Next.js for some time now, but I still find myself using the <img> tag for certain image components, like this one (using TailwindCSS). <div className="relative"> <div className= ...

The Next.js development was hindered by a webpack issue causing the build to

Whenever I try to build my next.js app using npm run build, npm fails and crashes while trying to access the logo.png file from the public directory. This directory is where all static assets like images and icons are stored, so I'm unsure why this er ...

Guide to refreshing a webpage using data retrieved from an ajax request

I'm currently working on an ejs file that contains a list of items sourced from a database. My goal is to implement a search feature that updates this list with the search results only. To achieve this, I've set up a post request to be sent to t ...

Is it possible to send a variable to a mandatory file?

While working with Express, I am attempting to move my minification process to a required file: app.js: var app = express(); var minify = require("./minify.js"); Within that file, I am trying to set my template engine. minify.js: var app = express(); ...

Docker containers do not allow environment variables to be overridden

I am relatively new to Docker and I have a Nextjs application running inside a docker container. This application utilizes certain environment variables for communication with the server. An issue arises where, despite passing the environment variables whe ...

After successfully logging in with Firebase, the login page still loads on index.tsx upon page refresh

I am currently working on a Next.js project with Firebase as the backend database. Within this project, there are multiple pages such as visitors.tsx, issues.tsx, and index.tsx (which serves as my login page). Upon logging in to the application, I am direc ...

What are the advantages of using global.mongoose for caching the MongoDB connection?

What is the reason for adding global.mongoose to cache the MongoDB connection? import mongoose from 'mongoose' let cached = global.mongoose if (!cached) { cached = global.mongoose = { conn: null, promise: null } } What is the purpose of this ...

Tips for transferring the button ID value to a GET request?

I recently developed a Node.js application that interacts with a database containing student information and their current marks. Utilizing MongoDB, I retrieve the data and present it in a table within an .ejs file. index.js router.get("/dashboard", funct ...

The tag dimensions are not displaying correctly

I've successfully developed a reusable heading component for my Next.js application. While debugging, it correctly displays the tag name, but unfortunately, there is no visual difference in styling at any level of tags. import React from 'react&a ...

After clicking on the checkbox, req.body.task becomes undefined

Whenever I click on the checkbox, the value of req.body.task returns as undefined. <input type="checkbox" name="task" autocomplete="off" checked="" onchange="onToDochange({{id}})"> This function is triggered by a change event on the checkbox and it ...