workerman icon indicating copy to clipboard operation
workerman copied to clipboard

Https (wss) error on connection

Open Muradg opened this issue 1 year ago • 4 comments

Hello. I have been struggling to launch a project on https for a long time. Using the http option and using the server's IP, everything works.

I have a subdomain like psql.site.ru

I start the worker using the code:

$context = array(
           'ssl' => array(
             'local_cert' => storage_path('app/certs/fullchain1.pem'), // cert
             'local_pk' => storage_path('app/certs/privkey1.pem'), // key
             'verify_peer' => false,
           )
);

$ws_worker = new Worker('websocket://psql.site.ru, $context);
$ws_worker->transport = 'ssl';
$ws_worker->count = 1;

.........

The certificate files are valid and their paths are correct. Rights exhibited 666

On the frontend side connect:

let ws = new WebSocket("wss://psql.site.ru/?token={{ $token }}");
ws.onmessage = function (evt) {
    console .log(evt);
}

document.getElementById('btn').addEventListener('click', function(t) {
    let data = {
       "event": "SEND_MESSAGE"
    };

    ws.send(JSON.stringify(data))
});

When i connect, i get an error: WebSocket connection to 'wss://psql.site.ru:2346/?token=123' failed:

And i get an error in "onerror" event:

Event {isTrusted: true, type: 'error', target: WebSocket, currentTarget: WebSocket, eventPhase: 2, …}
isTrusted: true
bubbles: false
cancelBubble: false
cancelable: false
composed: false
currentTarget: WebSocket {url: 'wss://psql.site.ru:2346/?token=123', readyState: 3, bufferedAmount: 0, onopen: ƒ, onerror: ƒ, …}
defaultPrevented: false
eventPhase: 0
returnValue: true
srcElement: WebSocket {url: 'wss://psql.site.ru:2346/?token=123', readyState: 3, bufferedAmount: 0, onopen: ƒ, onerror: ƒ, …}
target: WebSocket {url: 'wss://psql.site.ru:2346/?token=123', readyState: 3, bufferedAmount: 0, onopen: ƒ, onerror: ƒ, …}
timeStamp: 448.7000000476837
type: "error"

And i get error in "onclose":

CloseEvent {isTrusted: true, wasClean: false, code: 1006, reason: '', type: 'close', …}
isTrusted: true
bubbles: false
cancelBubble: false
cancelable: false
code: 1006
composed: false
currentTarget: WebSocket {url: 'wss://psql.site.ru:2346/?token=123', readyState: 3, bufferedAmount: 0, onopen: ƒ, onerror: ƒ, …}
defaultPrevented: false
eventPhase: 0
reason: ""
returnValue: true
srcElement: WebSocket {url: 'wss://psql.site.ru:2346/?token=123', readyState: 3, bufferedAmount: 0, onopen: ƒ, onerror: ƒ, …}
target: WebSocket {url: 'wss://psql.site.ru:2346/?token=123', readyState: 3, bufferedAmount: 0, onopen: ƒ, onerror: ƒ, …}
timeStamp: 449.60000002384186
type: "close"
wasClean: false

I use standard ports 2346 for connection. But when I change the ports to others (for example, 2246), the error does not immediately occur. It occurs when I try to send something to the server. I get an error like:

Uncaught DOMException: Failed to execute 'send' on 'WebSocket': Still in CONNECTING state.

Help please, can this error be due to the fact that the subdomain is used? Or was the certificate issued via lets encrypt ?

I will be very grateful, I have been trying to solve the problem for several days

Muradg avatar Feb 24 '23 19:02 Muradg

Change

$ws_worker = new Worker('websocket://psql.site.ru, $context);

to

$ws_worker = new Worker('websocket://0.0.0.0:443, $context);

and try again.

walkor avatar Feb 25 '23 08:02 walkor

Change

$ws_worker = new Worker('websocket://psql.site.ru, $context);

to

$ws_worker = new Worker('websocket://0.0.0.0:443, $context);

and try again.

THANK YOU VERY MATCH!!!!! Finally the problem is solved

please tell me why this option works, but not with the domain name? p.s. i had a typo i used $ws_worker = new Worker('websocket://psql.site.ru:2346', $context); But when I replaced the domain name with 0.0.0.0, everything worked!!

Muradg avatar Feb 25 '23 12:02 Muradg

Domain name only works if you have it defined in your servers Hosts file (first mechanism for domain name resolving to IP by OS). There can be three IP's, 127.0.0.1 (e.g. localhost in your /etc/hosts/ file) will create a listening socket available to your operating systems virtual ('fake') network loopback adapter. Only programs can connect to it which are running on your computer. If you define a address 0.0.0.0, it will open a listening socket for all network adapters available on your computer (including virtual ones). Defining a IP address your network interface has, it will only accept connections on the interface.

When you set the address to psql.site.ru, OS has no way of knowing the network adapters IP address to listen on. Either define it in your %WINDIR%/System32/drivers/etc/hosts e.g. 0.0.0.0 psql.site.ru and it will work.

akotulu avatar Mar 10 '23 23:03 akotulu

if you need ip use

$ip = gethostbyname('psql.site.ru');
$ws_worker = new Worker("websocket://{$ip}443", $context);

AliceSync avatar Mar 27 '23 16:03 AliceSync