javascriptnode.jsexpresswebsocket

Can't get Websockets / wss to work at all on simple app


I've been fiddling around with WebSockets the past few days and got some success. Particularly, I am able to have a client connect to a server over "ws://localhost:8080". However, the second I change this to "wss://localhost:8080", my client can no longer connect, and as the best the WebSocket API can tell me is "haha you got an error", and I have no idea how to fix this. I am using the Microsoft Edge browser to support the client, and node.js / express to set up the server. I have been scouring the web for answers to not much success. My only guess is that Edge is messing around with my WebSocket connections. Overall, my end goal with this is to fix another issue in one of my programs where "wss" connections worked for 2 weeks and then suddenly didn't. Any help or insight would be much appreciated.

Update: I got "wss" to work by exposing "localhost:8080" via ngrok. However, something even stranger happens -- half the time, the WebSocket connection is made and everything works fine. But the other half -- the websocket connection fails. I am really stuck.

Here is some relevant code:

Client:

<!DOCTYPE html>
<html lang='en'>
    <head>
        <meta charset='UTF-8'>
        <meta name="viewport" content = "width-device-width, initial-scale-1.0">
        <title>Socket Thing 1</title>
    </head>
    <body>
        Client1
        <button
            onclick="sendMessage()">Send Msg</button>
    </body>
    <script>
        const socket = new WebSocket('wss://localhost:8080');

        socket.addEventListener('open', function (event) {
            console.log('Connected to Web Socket server');
        });

        socket.addEventListener('message', function (event) {
            console.log("Client 1 received new message from server");
        });

        socket.onerror = (event) => {
            console.error("Web Socket error observed: " + event);
        }

        const sendMessage = () => {
            socket.send('Hello from Client1');
        }
    </script>
</html>

Server:

const express = require('express');
const app = express();
const server = require('http').createServer(app);
const WebSocket = require('ws');
const wss = new WebSocket.Server( { server });

wss.on('connection', ws => {
    console.log('New client connected');
    ws.send('Welcome new client');

    ws.on('message', message => {
        console.log('Received a message: ' + message);
        ws.send("Message from server: Got your message");
        wss.clients.forEach(function each(client) {
            // don't send to current ws client
            if (client !== ws && client.readyState === WebSocket.OPEN) {
              client.send(message); // send to all other clients
            }
          });
    });
});

app.get('/', (req, res) => res.send('Hello World!'));

server.listen(8080, () => console.log('Listening on port : 8080'));


Solution

  • It looks like your server can not satisfy a request comeing in via wss://. Handling communication through ws:// is different to wss:// . In order to do so you have, among other things, to let the server know where your cetificate and private key are located in order to start secure communication with your client.

    You probably get an idea reading this implementing-https-and-wss-support-in-express