Why am I encountering difficulties connecting to the Socket IO object in Node.js using Express?

Encountering a strange issue on the remote server side where everything works fine locally with a self-signed cert over https. However, when moving the code to the server, it works locally but not remotely.

A node app is created and hosted on the server using port 3000 for https. Socket IO lib is attached to the same https server. Nodeiis is not used; instead, rewrite rules are employed to pass it through Windows IIS.

The websocket module is already installed in IIS. Initially, websockets were used successfully with the current configuration before switching to Socket.IO which better suits the requirements.

Now onto the code

Html Page

<script src="/socket.io/socket.io.js"></script>
<script src="/js/Client.js"></script>

Client.js

$(document).ready(function() {

    var address = window.location.protocol + '//' + window.location.host;  
    var details = {  
       resource: (window.location.pathname.split('/').slice(0, -1).join('/') + '/socket.io').substring(1)  
    };  
    const socket = io.connect(address, details);

    socket.on('connect', function () {
        console.log('Client Connected');
        socket.emit('ping', 'hi server ping sent!');
    });

    socket.on('error', function (reason){
        console.log('Connection failed', reason); //This is where the error is triggered
    });
});

App.js

....
const https = require('https');

var socketlib = require('./socketLib');
const fs = require('fs');
const app = express();
var cookieParser = require('cookie-parser');
app.use(sessionParser);
var expiryDate = new Date( Date.now() + 60 * 60 * 1000 );

const sessionParser = session({
  secret: 'secret', resave: true, cookieName: 'sessionName',
  name: 'sessionId', saveUninitialized: true,
  ephemeral: true,
  cookie: { secure: true, expires: expiryDate, SameSite : 'None',
    maxAge: 24000 * 60 * 60, // One hour
  }
});

//// HTTPS Server ////
const options = {
  key: fs.readFileSync(config.certKey),
  cert: fs.readFileSync(config.certCert)
};

var httpsServer = https.createServer(options, app, function (req, res) {
    console.log('request starting...https');
});

httpsServer.listen(3000, function(req, res) {
  console.log('Server is running at', config.nodeApiUrl + ':', port)
});

socketlib(httpsServer, sessionParser);

app.all('/*', function (req, res, next) {
res.header('Access-Control-Allow-Origin', 'https://localhost:3000') 
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE')
res.header("Access-Control-Allow-Credentials", "true");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, X-Access-Token,X-Key");
    return next();
})

socketLib.js

module.exports = async function(httpsServer, sessionParser) {
    var io = require("socket.io")(httpsServer);

    io.use(function(socket, next) {
        sessionParser(socket.request, socket.request.res, next);
    });

    io.use((socket, next) => {
        if (socket.request.headers.cookie)
            return next();
        next(new Error('Authentication error'));
    });

    io.sockets.on('connection', function(socket) {
        console.log(`New connection from: ${socket.handshake.address}`)
    });
}

iis webconfig

<rule name="Websocket" stopProcessing="true" enabled="true">
      <match url="socket.io" ignoreCase="true" />
      <action type="Rewrite" url="https://localhost:3000/{R:0}/socket.io.js" appendQueryString="false" redirectType="Found" />
        <conditions>
           <add input="{HTTP_HOST}" pattern="domainxxx.com" />
        </conditions>
    </rule> 

Browser Console Error:

socketio.js:57 Error Error: server error
    at r.onPacket (socket.io.js:7)
    at o.<anonymous> (socket.io.js:7)
    at o.r.emit (socket.io.js:6)
    at o.r.onPacket (socket.io.js:7)
    at n (socket.io.js:7)
    at Object.e.decodePayload (socket.io.js:7)
    at o.r.onData (socket.io.js:7)
    at i.<anonymous> (socket.io.js:7)
    at i.r.emit (socket.io.js:6)
    at i.onData (socket.io.js:7)

This points to:

switch(a('socket receive: type "%s", data "%s"',t.type,t.data),this.emit("packet",t),this.emit("heartbeat"),t.type){case"open":this.onHandshake(JSON.parse(t.data));break;case"pong":this.setPing(),this.emit("pong");break;case"error":var e=new Error("server error");e.code=t.data,this.onError(e);break;

You will see the line:

var e=new Error("server error")

When trying to access via domainxxx.com, it seems that something prevents the socket from connecting remotely while working fine locally. It appears that the issue arises after the rewrite rule, although it seems correct.

Your assistance in resolving this would be greatly appreciated as extensive research has been inconclusive!

Thank you very much!

Answer №1

After finding an old post from 4 years ago, I was able to successfully resolve the issue at hand. The problem lay in the rewrite rule, which I promptly replaced with the code snippet below, resulting in a seamless resolution:

        <rule name="WebSocketTestRule" stopProcessing="true">
            <match url=".*" />
            <conditions>
                <add input="{CACHE_URL}" pattern="domainxxx.com" />
            </conditions>
            <action type="Rewrite" url="https://localhost:3000/{R:0}" />
        </rule> 

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

Send all of the elements within an array as arguments to a function

My challenge involves working with an array of values: ['a', 'b', 'c', 'd'] I must pass these values as parameters to a function like this: window.myFunction('a', 'b', 'c', 'd&ap ...

Version 4.6.4 of TypeScript is flagging the code as invalid

How can I fix this Typescript problem? const userInformation: { email: string; id: string; _token: string; _tokenExpirationDate: string; } = JSON.parse(localStorage.getItem('userData')); Console Error Message Error: ...

Persist form data in MongoDB using Node.js and Express

Hello, I am able to successfully connect and store data in MongoDB using mLab. However, I am facing an issue where the data in the form does not remain on refresh. The form is designed to take user input from input boxes. I would greatly appreciate any as ...

Print directly without the need for a preview or dialog box

Is there a way to easily print content with just one click, without having to go through the preview or print dialog box? Here is a snippet of my code: <head> <style type="text/css"> #printable { display: none; } @media print { #non-pr ...

Express: Routes for directing requests to designated handlers

I have set up an Express app with a all('/', ...) handler on the main path. Within this handler, I am checking for a failure flag and need to make a decision on whether to proceed to the next handler or directly route the request to the /error en ...

Setting a fixed data value within a div for subsequent retrieval through a function

I found a helpful example that demonstrates how to convert numbers into words. You can check it out here. The function for converting numbers into words is implemented in the following HTML code: <input type="text" name="number" placeholder="Number OR ...

Attempting to retrieve an entity from the datastore, only to receive an undefined result, indicating that it was not

Currently, I am delving into the world of Google Datastore with node.js. After successfully storing an entity on the server, I encountered a challenge when trying to retrieve the newly created entity from my datastore. namespace: default kind: User http ...

Expo cannot be located in this project. Did you already run yarn/npm install? Npm is installed and the expo directory is present

My Expo project has been plagued with errors, reaching a peak when it threw an unfamiliar error at me: module not found: can't resolve '../utilities/platform' This occurred while I was working in a styling file. Even after deleting the file ...

Having trouble integrating express-validator with express version 3.x

Having trouble with using express-validator in conjunction with Express 3.0. Whenever I try to call the following code: expressValidator = require("express-validator") app.use(expressValidator) req.assert(req.body.password,'Enter Password').no ...

Utilizing Dynamic Image Sources in Vue.js with the Help of APIs

Can someone help me figure out how to solve this issue? I have an API that returns a base64 image, and I want to load this image on my site. Any suggestions on where or how I should implement my function? This is the API call located in the methods: metho ...

Is it possible to retrieve JSON data and display only the entries with positive values in an HTML

I am working on a project that involves fetching JSON API data and displaying it in an HTML table, but only for values above 10. Below is the code snippet along with my JavaScript. I specifically want to exclude negative values and only display positive v ...

The generation of a JWT is not possible in Node

Currently, I am utilizing the jsonwebtoken library to create a jwt token. Below is my user model structure: const userSchema = new mongoose.Schema({ username: { type: String, required: true, }, password: { type: String, required: tru ...

How to Incorporate an Anchor Link into a Div as well as its Pseudo Element using CSS, Javascript, or jQuery

How can I make both the menu item and its icon clickable as a link? When either is clicked, the link should work. Here is a CodePen example: http://codepen.io/emilychews/pen/wJrqaR The red square serves as the container for the icon that will be used. ...

Javascript Calculator with Dual Input Fields

I have been given a task to create a calculator by tomorrow using Javascript. Unfortunately, I am currently taking a distance course and Javascript has just been introduced in this assignment. While I am familiar with HTML and CSS, Javascript is something ...

What mistake am I making with arrays?

My understanding of JavaScript and Node.JS is still developing, so I'm puzzled as to why I'm receiving NaN when using this expression: var aUsersBetted = {}; aUsersBetted['1337'] += 200000; logger.debug(aUsersBetted['1337']); ...

Is it possible to scroll by using the dragenter event?

Looking for a way to achieve incremental scroll up and scroll down using jQuery without jQuery UI? Here's the scenario - I have two divs: <div class="upper" style="height:35px;background-color:red;right:0;left:0;top:0;position:fixed;width:100%;z-i ...

Class does not have the capability to deserialize an array

I encountered this issue with my code (see image): Here is the snippet of my code: function CheckLoginData() { var user = []; user.Email = $("#tbEmail").val(); user.Password = $("#tbPassword").val(); $.ajax({ type: "POST", contentType: "applic ...

What is causing the sorting table to fail in React when using useState?

import React, { useState } from "react"; import "./App.css"; const App = () => { const [data, setData] = useState([ { rank: 1, name: "John", age: 29, job: "Web developer", }, { rank: 2, name: "Micha ...

Ways to release the binding of an element and then re-enable it for future use

Encountering an issue with dynamically unbinding and binding elements using jQuery. Currently working on creating a mobile tabbing system where users can navigate using left and right arrows to move content within ul.tube. The right arrow shifts the ul.tu ...

Clicking a button in jQuery to load the Pagemethods

<script type="text/javascript"> $(document).ready(function() { $('#loadbtn').click(function() { // can 't load opts = { title: 'ABCD', series: [{ ...