Lost Connection to server, reconnecting on AWS linux

I've told you multiple times now - websockets use the port of the web server that hosts them, they do not have a separate port.

From Colin:

There are tools that you can use to check whether a websocket port is open on a server.

I obviously have the node-red https port open. So if there is no other port for "web socket" then I've done all that I know how to do as an installer of node-red.

Does anyone have a simple program I can try that encompass the node-red setting up a web socket while using the main port (eg 2000)?

I generally don't use the stand-alone websockets because I use UIBUILDER which bakes Socket.IO into it.

But this should be about as basic as it gets:

[{"id":"7ad569cbdbed633f","type":"websocket in","z":"b2f18a716bd20f99","name":"","server":"51674fc7568039c1","client":"","x":450,"y":1980,"wires":[["11641b147fba7261"]]},{"id":"2b51769d846a2647","type":"websocket out","z":"b2f18a716bd20f99","name":"","server":"51674fc7568039c1","client":"","x":640,"y":2040,"wires":[]},{"id":"11641b147fba7261","type":"debug","z":"b2f18a716bd20f99","name":"debug 38","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":620,"y":1980,"wires":[]},{"id":"3aa26bc75d8393cc","type":"inject","z":"b2f18a716bd20f99","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":460,"y":2040,"wires":[["2b51769d846a2647"]]},{"id":"51674fc7568039c1","type":"websocket-listener","path":"/myws","wholemsg":"false"}]

(Your path probably won't have the /nr on the front, that's just my dev setup).

As has been suggested multiple times, this is probably nothing to do with node red. The websocket uses the same port as node red, but it is a different protocol. If your AWS instance is not configured to support that then you will get the symptom that you see. Did you try a websocket tester as I suggested?

Just as a thought, let's look at this from the other end.

If I have understood correctly, the Node-RED instance is running on a AWS EC2 instance that has port 1880 (or some other configured port) open in both the OS firewall and the AWS Security Group.

What about the browser, where is that running, is it always from the same location (e.g. home or an office)?

If an office, does it have any HTTP Proxy enabled (not a reverse proxy on the AWS EC2 machine), but maybe something like Squid?

It may not be explicitly configured, it may be a transparent proxy ennoblement that grabs all outbound HTTP traffic. If this is not enabled for WebSockets then that could also be the problem.

It would also probably be useful to see the browsers network tab in the developer tools, we will be looking for a request to /comms

This for the ideas.

If I have understood correctly, the Node-RED instance is running on a AWS EC2 instance that has port 1880 (or some other configured port) open in both the OS firewall and the AWS Security Group.

Yes.

What about the browser, where is that running, is it always from the same location (e.g. home or an office)?

I have tried various browsers from my iPhone to my normal MacBook - and there are no proxy's on my end.

It would also probably be useful to see the browsers network tab in the developer tools, we will be looking for a request to /comms

This is the error in my browser:

WebSocket connection to 'wss://semanticmarkers.com/bot/comms' failed: There was a bad response from the server.

And the httpd error repeats that:
SemanticMarkers.com.request_log-20260510:[08/May/2026:16:25:15 +0000] 75.213.29.86 TLSv1.3 TLS_AES_256_GCM_SHA384 "GET /bot/comms HTTP/1.1" 144

@TotallyInformation I'm trying the standalone WebSocket now

I'm trying a WebSocket flow as a server, and this isn't working. Can you try it from your browser to see if this is the right way to start a websocket server (eg. ws/simple). This goes to my node-red sever.

I'll do some research at the AWS WebSocket side as well.

[
    {
        "id": "e471c1417f0ee229",
        "type": "tab",
        "label": "Flow 2",
        "disabled": false,
        "info": "",
        "env": []
    },
    {
        "id": "e3e4522e.1c1bb",
        "type": "inject",
        "z": "e471c1417f0ee229",
        "name": "Tick every 5 secs",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "30",
        "crontab": "",
        "once": false,
        "onceDelay": "",
        "topic": "test",
        "payload": "",
        "payloadType": "date",
        "x": 270,
        "y": 300,
        "wires": [
            [
                "45dbf990.ba2408"
            ]
        ]
    },
    {
        "id": "50da04b3.af25fc",
        "type": "websocket out",
        "z": "e471c1417f0ee229",
        "name": "",
        "server": "07a7e0858e615378",
        "client": "",
        "x": 740,
        "y": 300,
        "wires": []
    },
    {
        "id": "42a28745.bd5d78",
        "type": "http response",
        "z": "e471c1417f0ee229",
        "name": "",
        "x": 721,
        "y": 240,
        "wires": []
    },
    {
        "id": "1787be40.e87842",
        "type": "http in",
        "z": "e471c1417f0ee229",
        "name": "",
        "url": "/simple",
        "method": "get",
        "swaggerDoc": "",
        "x": 352,
        "y": 240,
        "wires": [
            [
                "1857548e.e7a8ab"
            ]
        ]
    },
    {
        "id": "1857548e.e7a8ab",
        "type": "template",
        "z": "e471c1417f0ee229",
        "name": "Simple Web Page",
        "field": "payload",
        "fieldType": "msg",
        "format": "html",
        "syntax": "mustache",
        "template": "<!DOCTYPE HTML>\n<html>\n    <head>\n    <title>Simple Live Display</title>\n    <script type=\"text/javascript\">\n        var ws;\n        var wsUri = \"ws:\";\n        var loc = window.location;\n        console.log(loc);\n        if (loc.protocol === \"https:\") { wsUri = \"wss:\"; }\n        // This needs to point to the web socket in the Node-RED flow\n        // ... in this case it's ws/simple\n        wsUri += \"//\" + \"SemanticMarkers.com/bot/ws/simple\";\n        console.log(wsUri);\n\n        function wsConnect() {\n            console.log(\"connect\",wsUri);\n            ws = new WebSocket(wsUri);\n            //var line = \"\";    // either uncomment this for a building list of messages\n            ws.onmessage = function(msg) {\n                var line = \"\";  // or uncomment this to overwrite the existing message\n                // parse the incoming message as a JSON object\n                var data = msg.data;\n                console.log(data);\n                // build the output from the topic and payload parts of the object\n                line += \"<p>\"+data+\"</p>\";\n                // replace the messages div with the new \"line\"\n                document.getElementById('messages').innerHTML = line;\n                //ws.send(JSON.stringify({data:data}));\n            }\n            ws.onopen = function() {\n                // update the status div with the connection status\n                document.getElementById('status').innerHTML = \"connected\";\n                ws.send(\"Open for data\");\n                console.log(\"connected\");\n            }\n            ws.onclose = function() {\n                // update the status div with the connection status\n                document.getElementById('status').innerHTML = \"not connected\";\n                // in case of lost connection tries to reconnect every 3 secs\n                setTimeout(wsConnect,3000);\n            }\n            ws.disconnect = function() {\n                console.log(\"Disconnected\");\n                document.getElementById('status').innerHTML = \"disconnected\";\n            }\n        }\n        \n        function doit(m) {\n            if (ws) { ws.send(m); }\n        }\n    </script>\n    </head>\n    <body onload=\"wsConnect();\" onunload=\"ws.disconnect();\">\n        <font face=\"Arial\">\n        <h1>Simple Live Display</h1>\n        <div id=\"messages\"></div>\n        <button type=\"button\" onclick='doit(\"click\");'>Click to send message</button>\n        <hr/>\n        <div id=\"status\">unknown</div>\n        </font>\n    </body>\n</html>\n",
        "x": 549,
        "y": 240,
        "wires": [
            [
                "42a28745.bd5d78"
            ]
        ]
    },
    {
        "id": "45dbf990.ba2408",
        "type": "function",
        "z": "e471c1417f0ee229",
        "name": "format time nicely",
        "func": "msg.payload = Date(msg.payload).toString();\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "x": 510,
        "y": 300,
        "wires": [
            [
                "50da04b3.af25fc",
                "9095309e5a6340c9"
            ]
        ]
    },
    {
        "id": "eccc8bc2.133378",
        "type": "websocket in",
        "z": "e471c1417f0ee229",
        "name": "",
        "server": "07a7e0858e615378",
        "client": "",
        "x": 460,
        "y": 380,
        "wires": [
            [
                "9adfff59.652"
            ]
        ]
    },
    {
        "id": "9adfff59.652",
        "type": "debug",
        "z": "e471c1417f0ee229",
        "name": "Received Websocket /ws/simple",
        "active": true,
        "tosidebar": true,
        "console": true,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 740,
        "y": 380,
        "wires": []
    },
    {
        "id": "9095309e5a6340c9",
        "type": "debug",
        "z": "e471c1417f0ee229",
        "name": "Sent Websocket /ws/simple",
        "active": true,
        "tosidebar": true,
        "console": true,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 970,
        "y": 320,
        "wires": []
    },
    {
        "id": "07a7e0858e615378",
        "type": "websocket-listener",
        "path": "/ws/simple",
        "wholemsg": "false"
    }
]

OK .. this is interesting. I do NOT get the lost connection if I use the PORT number, versus my http rewrite.

So SemanticMarkers.com:2000 (works)
vs SemanticMarkers.com/bot

The Rewrite rule is:

# node-red
   # /bot-> :2000
   RewriteRule ^/bot$ bot/ [L,R=301]
   ProxyPass "/bot" "https://SemanticMarkers.com:2000"
   ProxyPassReverse "/bot" "https://SemanticMarkers.com:2000"

So I think this is an Apache HTTPD server issue. For example this: Apache ProxyPass websocket problem · Issue #3339 · meteor/meteor · GitHub
and

Apache mod_rewrite often breaks WebSockets because it doesn't automatically handle the "Upgrade" mechanism that switches a connection from HTTP to the WebSocket protocol. Standard rewrite rules typically treat WebSocket handshakes as regular HTTP requests, which can lead to dropped connections or "400 Bad Request" errors. [1, 2, 3, 4]

Thanks so much..

:enraged_face:

So this is a proxy that I warned you about - I think in my very first response. But you never told us that you'd put a proxy in front of everything even though we asked repeatedly.

And to be clear, not a Node-RED issue at all.

When asking for help, please be clear about your environment - and take care to listen to advice and work through it carefully.

Thanks for the help. I wasn't thinking "proxy" but rather "rewrite" since they are using the httpd server. I assumed a proxy was a separate process (other than httpd).

Thanks, everyone.