websockets / ws

Simple to use, blazing fast and thoroughly tested WebSocket client and server for Node.js
MIT License
21.34k stars 2.3k forks source link

The code isn't working. #2202

Closed andrys2007 closed 4 months ago

andrys2007 commented 4 months ago

Is there an existing issue for this?

Description

Greetings, everyone. I downloaded this code. I wanted to check how WebSockets with SSL (WSS) work. I'm running the example ..\examples\ssl.js

In it, I explicitly specified the port: 3300


'use strict';

const PORT=3300;

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

const { WebSocket, WebSocketServer } = require('..');

const server = https.createServer({
  cert: fs.readFileSync('../test/fixtures/certificate.pem'),
  key: fs.readFileSync('../test/fixtures/key.pem')
});

const wss = new WebSocketServer({ server });

wss.on('connection', function connection(ws) {
  ws.on('error', console.error);

  ws.on('message', function message(msg) {
    console.log(msg.toString());
  });
});

server.listen(3300,function listening() {
  //
  // If the `rejectUnauthorized` option is not `false`, the server certificate
  // is verified against a list of well-known CAs. An 'error' event is emitted
  // if verification fails.
  //
  // The certificate used in this example is self-signed so `rejectUnauthorized`
  // is set to `false`.
  //  server.address().port

  const ws = new WebSocket(`wss://localhost:${PORT}`, {
    rejectUnauthorized: false
  });

  ws.on('error', console.error);

  ws.on('open', function open() {
    ws.send('All glory to WebSockets!');
  });
});

But for some reason, the example doesn't work. What could be the problem?

I tried another option:

const fs = require('fs');
const https = require('https');
const WebSocket = require('ws');

const server = https.createServer({
    cert: fs.readFileSync(__dirname + '/ssl/certificate.crt'),
    key: fs.readFileSync(__dirname + '/ssl/private.key'),
});
const wss = new WebSocket.Server({ server });

wss.on('connection', function connection(ws) {
    ws.on('message', (function(ws){ return function incoming(message) {
        console.log('received %s', message);
        ws.send(message);
        if(message == 'close'){
            ws.close();
        }else if(message == 'shutdown'){
            ws.close();
            wss.close();
            console.log('Stop server');
            process.exit();
        }
    }})(ws));

    ws.send('Welcome');
});

server.listen(3300);
console.log('Run server');

Port 3300 is open for me, I'm checking the WS server on it, everything works fine.

ws version

wss

Node.js Version

v20.11.1

System

Window 10, window server 2019

Expected result

not

Actual result

not

Attachments

not

lpinca commented 4 months ago

Are you getting any errors? I've just tested it and the example in https://github.com/websockets/ws/blob/5e42cfdc5fa114659908eaad4d9ead7d5051d740/examples/ssl.js works fine.

andrys2007 commented 4 months ago

Hello. No, there are no errors. It just doesn't connect. It doesn't respond in any way. At the same time, if I run the WS code, it works fine, but the problem is specifically with WSS. Could the issue be with the certificates? I'm connecting from this client: https://test2.e-task.kz/ (test).

andrys2007 commented 4 months ago

look WS server and clinet :

const WebSocket = require('ws');
const wsServer = new WebSocket.Server({ port: 3300 });

wsServer.on('connection', onConnect);

function onConnect(wsClient) {
    console.log('New user');
    wsClient.send('Hi');

    wsClient.on('close', function() {
        console.log('User disconnected');
    });

    wsClient.on('message', function(message) {
        console.log(message);
        try {
            const jsonMessage = JSON.parse(message);
            switch (jsonMessage.action) {
                case 'ECHO':
                    wsClient.send(jsonMessage.data);
                    break;
                case 'PING':
                    setTimeout(function() {
                        wsClient.send('PONG');
                    }, 2000);
                    break;
                default:
                    console.log('bad command');
                    break;
            }
        } catch (error) {
            console.log('error', error);
        }
    });
}

console.log('server start. Port: 3300 ');

Test clinet ws: http://test.lorcenter.kz/

This code works.

lpinca commented 4 months ago

Could the issue be with the certificates?

Yes. The certificate in the example is self signed. It looks like Chrome does not give you details but if you open the console in Safari and write this code

new WebSocket('wss://192.168.1.188:3300')

you get something like this

WebSocket connection to 'wss://192.168.1.188:3300/' failed: The certificate for this server is invalid. You might be connecting to a server that is pretending to be “192.168.1.188” which could put your confidential information at risk.

This is not a ws issue.

andrys2007 commented 4 months ago

I checked in Firefox, Chrome, and Opera.

andrys2007 commented 4 months ago

I've made new certificates, but it still doesn't help. How else can we test it?

andrys2007 commented 4 months ago

For example, maybe we can first test HTTPS to see if it works and then test WSS

lpinca commented 4 months ago

I've made new certificates, but it still doesn't help. How else can we test it?

The certificate must be signed by a trusted CA.

lpinca commented 4 months ago

For example, maybe we can first test HTTPS to see if it works and then test WSS.

Yes, you can use OpenSSL. For example:

openssl s_client -connect websocket-echo.com:443
andrys2007 commented 4 months ago

How can I make a proper certificate? After all, it shouldn't be tied to a specific domain

lpinca commented 4 months ago

It should. Certificates are for domains. For local testing you can use something like this https://github.com/FiloSottile/mkcert.

andrys2007 commented 4 months ago

The thing is, the local one doesn't work either. Okay, I'll try to do it through a trusted organization now. I'll let you know about the results

lpinca commented 4 months ago

I'm closing this as answered.

andrys2007 commented 4 months ago

Now I'm starting to understand, and it turns out that the connection must be made on a host with a domain name. Moreover, they write that for WSS, you need to connect via the domain name, only through WSS://domainname.com. I wonder how this will look in the settings?