'Problem to use Websocket in React with express server

I want to integrate a simple websocket message function in react in combination with a react server. This is my code for the react part:

{import React, { Component, useState, useRef, useLayoutEffect, useEffect } from 'react';

class ChildComponent extends Component {

sendMessage=()=>{
    const {websocket} = this.props // websocket instance passed as props to the child component.

    try {
        //websocket.send(data) //send data to the server
        websocket.send('ping') //send data to the server

    } catch (error) {
        console.log(error) // catch error
    }
}

render() {
    return (
        <div>
            <button
                onClick={this.sendMessage}
                >
                Click me to say Hallo
            </button>
           </div>
    );
}
}
export default class Messenger extends Component {
constructor(props) {
    super(props);

    this.state = {
        ws: null,
          };
}

// single websocket instance for the own application and constantly trying to reconnect.

componentDidMount() {
    this.connect();
}

timeout = 250; // Initial timeout duration as a class variable

/**
 * @function connect
 * This function establishes the connect with the websocket and also ensures constant reconnection if connection closes
 */
connect = () => {
    var ws = new WebSocket("ws://localhost:8000");

    let that = this; // cache the this
    var connectInterval;

    // websocket onopen event listener
    ws.onopen = () => {
        console.log("connected websocket main component");

        this.setState({ ws: ws });
        that.timeout = 250; // reset timer to 250 on open of websocket connection
        clearTimeout(connectInterval); // clear Interval on open of websocket connection
    };

    // websocket onclose event listener
    ws.onclose = e => {
        console.log(
            `Socket is closed. Reconnect will be attempted in ${Math.min(
                10000 / 1000,
                (that.timeout + that.timeout) / 1000
            )} second.`,
            e.reason
        );

        that.timeout = that.timeout + that.timeout; //increment retry interval
        connectInterval = setTimeout(this.check, Math.min(10000, that.timeout)); //call check function after timeout
    };

    ws.onmessage = evt => {
        // listen to data sent from the websocket server
        const message = JSON.parse(evt.data)
        this.setState({dataFromServer: message})
        console.log(message)
        alert('message')
    }

    // websocket onerror event listener
    ws.onerror = err => {
        console.error(
            "Socket encountered error: ",
            err.message,
            "Closing socket"
        );

        ws.close();
    };
};

/**
 * utilited by the @function connect to check if the connection is close, if so attempts to reconnect
 */
check = () => {
    const { ws } = this.state;
    if (!ws || ws.readyState == WebSocket.CLOSED) this.connect(); //check if websocket instance is closed, if so call `connect` function.
};

render() {

    return <ChildComponent websocket={this.state.ws} />;

}
}}

This should work without integrating packages. But it doesn't. Thus I installed websockt in the express server and configured it with this code:

require('dotenv').config();
const express = require('express');
const http = require('http');
const ws = require('ws');
const axios = require('axios');
const bodyParser = require('body-parser'); 
const pino = require('express-pino-logger')();
const app = express();

app.use(bodyParser.json());
app.use(bodyParser.urlencoded());
app.use(pino);
...    
const server = app.listen(8000);

server.on('upgrade', (request, socket, head) => {
wsServer.handleUpgrade(request, socket, head, socket => {
    wsServer.emit('connection', socket, request);
});
});

const wsServer = new ws.Server({ noServer: true });

wsServer.on('connection', socket => {
console.log("Connected WebSocket")
socket.on('message', data => {
    //const message = JSON.parse(data);
    console.log(data);
});
});

app.listen(3001, () =>
console.log('Express server is running on localhost:3001')
);

When clicking on the button to send a message, console logs some buffer code. But I don't think this is the way it should work. From the react server none of the console log information is shown in the terminal. Especially ws.onmessage from the react part doesn't show the integrated alert. What is to do on the express server side to get it work correctly?



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source