I have followed tutorials to configure laravel with websockets using docker, except that my php version is PHP 8.1.9, and laravel 8.
My nginx container is a reverse proxy to web_dev container, and does SSL termination. So further communication internally is over http.
nginx.conf
server {
listen 80;
server_name mydomain.co.uk *.mydomain.co.uk;
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
server_name mydomain.co.uk *.mydomain.co.uk;
include common.conf;
include ssl.conf;
location / {
include common_location.conf;
proxy_pass http://web_dev;
}
}
server {
listen 6001 ssl;
server_name mydomain.co.uk *.mydomain.co.uk;
include common.conf;
include ssl.conf;
location /ws {
proxy_read_timeout 60;
proxy_connect_timeout 60;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_cache_bypass $http_upgrade;
proxy_set_header Sec-WebSocket-Key 'SGVsbG8sIHdvcmxkIQAAAA==';
proxy_set_header Sec-WebSocket-Version '13';
include common_location.conf;
proxy_pass http://web_dev:6001/;
}
}
Then I have a curl command:
curl -k \
--no-buffer \
--header "Connection: upgrade" \
--header "Upgrade: websocket" \
-v \
https://mydomain.co.uk:6001/ws/app/mydomainkey
This is the output:
Connected to mydomain.co.uk (127.0.0.1) port 6001 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* TLSv1.0 (OUT), TLS header, Certificate Status (22):
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS header, Certificate Status (22):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
....
* TLSv1.2 (IN), TLS handshake, Finished (20):
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
> GET /ws/app/mydomainkey HTTP/1.1
> Host: mydomain.co.uk:6001
> User-Agent: curl/7.81.0
> Accept: */*
> Connection: upgrade
> Upgrade: websocket
>
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* Mark bundle as not supporting multiuse
< HTTP/1.1 101 Switching Protocols
< Server: nginx/1.21.5
< Date: Sun, 04 Sep 2022 12:00:33 GMT
< Connection: upgrade
< Upgrade: websocket
< Sec-WebSocket-Accept: 5Tz1rM6Lpj3X4PQub3+HhJRM11s=
< X-Powered-By: Ratchet/0.4.4
< Strict-Transport-Security: max-age=31536000; includeSubDomains
<
* TLSv1.2 (IN), TLS header, Supplemental data (23):
�r{"event":"pusher:connection_established","data":"{\"socket_id\":\"155833011.137698690\",\"activity_timeout\":30}"}
This I think shows that the port 6001 and the SSL are configured correctly and that the websocket connection was established.
When I go to the url for websockets dashboard and click connect, I get
WebSocket connection to 'wss://mydomain.co.uk:6001/ws/app/bookhaircut?protocol=7&client=js&version=4.3.1&flash=false' failed:
I also tried fetch("wss://mydomain.co.uk:6001/ws/app/mydomainkey?protocol=7&client=js&version=4.3.1&flash=false");
which gives a different error:
On the web_dev container, I'm running supervisor which runs php artisan websockets:serve
. I can verify that my web_dev container can connect to its websockets running service, because I ran in php artisan tinker
:
`event (new \App\Events\NewTrade('test'))`
=> []
Then I checked supervisor logs I get many entries:
So in conclusion:
- nginx is serving correctly because curl command works correctly with nginx with SSL (this also generates log entries in supervisor)
- laravel is internally connecting correctly
- But pusher-js in web browser is complaining that wss scheme is not supported and that websocket connection failed. My nginx version: nginx/1.21.5
- I'm not even using Echo yet. Echo uses pusher-js, and the dashboard is implemented using pusher-js. So if the dashboard doesn't work, nor will my Echo work.
- I have now down-graded my pusher to 4.3.1 in package.json but that didn't do anything because the version is hardcoded in the dashboard (also 4.3 though).
Any ideas?
I tried to modify the dashboard to pull a different version https://cdnjs.cloudflare.com/ajax/libs/pusher/6.0.3/pusher.js And that didnt make any difference.
Could nginx support wss instead of http? I have only seen configs with http. Configs with wss: throw an error.
So I'm out of ideas.
Here's my config files:
websockets.php
'apps' => [
[
'id' => env('PUSHER_APP_ID'),
'name' => env('APP_NAME'),
'key' => env('PUSHER_APP_KEY'),
'secret' => env('PUSHER_APP_SECRET'),
'path' => "/ws",
'capacity' => null,
'enable_client_messages' => false,
'enable_statistics' => true,
],
],
/* ssl is left empty.*/
related problems: