menu

arrow_back Laravel + Nuxt + Nginx: WebSocket is closed before the connection is established?

by
2 votes
General scheme and project configuration files

The project consists of two parts:
Server part - Laravel (api)
Client part - NuxtJs (client)
A minimal configuration of the project was prepared for the test.

Laravel

Web socket packages are installed:
beyondcode/laravel-websockets: https://beyondco.de/docs/laravel-websockets/gettin...
pusher/pusher-php-server: https://pusher.com/tutorials/web-notifications-lar...
Файл composer.json:
...
"require": {
"php": "^7.3",
"beyondcode/laravel-websockets": "^1.8",
"fideloper/proxy": "^4.2",
"fruitcake/laravel-cors": "^2.0",
"guzzlehttp/guzzle": "^7.0.1",
"laravel/framework": "^8.0",
"laravel/tinker": "^2.0",
"pusher/pusher-php-server": "^4.1"
},
"require-dev": {
"facade/ignition": "^2.3.6",
"fzaninotto/faker": "^1.9.1",
"mockery/mockery": "^1.3.1",
"nunomaduro/collision": "^5.0",
"phpunit/phpunit": "^9.3"
},
...
Nuxt Web socket packages are installed: nuxtjs/laravel-echo: https://github.com/nuxt-community/laravel-echo
pusher-js: https://github.com/pusher/pusher-js The package.json file:
...
"dependencies": {
"@nuxtjs/axios": "^5.12.2",
"@nuxtjs/dotenv": "^1.4.1",
"@nuxtjs/laravel-echo": "^1.1.0",
"@nuxtjs/proxy": "^2.0.1",
"nuxt": "^2.13.0",
"pusher-js": "^7.0.0"
},
...
//--- All files are already uploaded to the VPS ( Ubuntu 18.04 LTS) and a certificate is obtained ( https://certbot.eff.org/ ): 5f9047746d3a3314117831.png

The web socket server is up and running permanently according to this description: https://beyondco.de/docs/laravel-websockets/basic-...

Verification:

supervisorctl status

5f904e57d82ae148020652.png

To automatically start and restart the client part, the process manager is globally installed and running on a permanent basis pm2 : https://pm2.keymetrics.io

Verification:

pm2 list

5f904e9796e01163828440.png

A list of busy ports:

netstat -ntlp | grep LISTEN

5f904ef0363e9041645358.png



lsof -i -P -n | grep LISTEN



5f904f0d8ff57108340234.png



Текущий статус сетевой защиты:



ufw status



5f904f3667e1e890440572.png



//---



Ответ от серверной части, при запросах из клиентской, приходит:



5f904f699f319834915643.png



С веб-сокетами получается ошибка:



5f904fb70b9fe375398259.png

5f904fc0b916b472485083.png



Файлы для настройки веб-сокетов



Laravel



Файл .env:



vim /var/www/api/.env



APP_NAME=Laranuxt
APP_ENV=production
APP_KEY=base64:cSTA4y9lIjmQDQ9b3+J2X+iSif8jqu6u3Oj9UNXdzIs=
APP_DEBUG=false
APP_SCHEME=https://
APP_HOST=larastart.site
APP_URL="${APP_SCHEME}larastart.site"
CLIENT_URL="${APP_SCHEME}larastart.site"
...
PUSHER_APP_ID=123
PUSHER_APP_KEY=456
PUSHER_APP_SECRET=789
PUSHER_APP_CLUSTER=test

MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"




Файл websockets.php:



vim /var/www/api/config/websockets.php



...
'apps' => [
[
'id' => env('PUSHER_APP_ID'),
'name' => env('APP_NAME'),
'key' => env('PUSHER_APP_KEY'),
'secret' => env('PUSHER_APP_SECRET'),
'path' => env('PUSHER_APP_PATH'),
'capacity' => null,
'enable_client_messages' => true,
'enable_statistics' => false,
],
],
...




Файл broadcasting.php:



vim /var/www/api/config/broadcasting.php



...
'connections' => [
'pusher' => [
'driver' => 'pusher',
'key' => env('PUSHER_APP_KEY'),
'secret' => env('PUSHER_APP_SECRET'),
'app_id' => env('PUSHER_APP_ID'),
'options' => [
'cluster' => env('PUSHER_APP_CLUSTER'),
'useTLS' => false,
'encrypted' => false,
'host' => env('APP_HOST'),
'port' => 6001,
'scheme' => 'http',
'curl_options' => [
CURLOPT_SSL_VERIFYHOST => 0,
CURLOPT_SSL_VERIFYPEER => 0,
]
],
],
...
],
...




Nuxt



cd /var/www/client



Файл .env:



vim /var/www/client/.env



SCHEME     = https://
BASE_URL = "${SCHEME}larastart.site"
API_DOMAIN = "${SCHEME}larastart.site"
API_URL = "${SCHEME}larastart.site/api"

BROADCAST_DRIVER = pusher
PUSHER_APP_ID = 123
PUSHER_APP_KEY = 456
PUSHER_APP_SECRET = 789
PUSHER_APP_CLUSTER = test




Файл echo.js:



vim /var/www/client/plugins/echo.js



import Echo from 'laravel-echo';

export default (app) => {
window.Pusher = require('pusher-js');

window.Echo = new Echo({
broadcaster: process.env.BROADCAST_DRIVER,
key: process.env.PUSHER_APP_KEY,
cluster: process.env.PUSHER_APP_CLUSTER,

forceTLS: false,
encrypted: false,
wsHost: window.location.hostname,
wsPort: 6001,
wssPort: 6001,
disableStats: false,
enabledTransports: ['ws', 'wss']
});
}




Файл nuxt.config.js:



vim /var/www/client/nuxt.config.js



...
plugins: [
{ src: '~/plugins/echo.js', ssr: false }
],
modules: [
'@nuxtjs/axios',
'@nuxtjs/proxy',
'@nuxtjs/dotenv'
],
axios: {
baseURL: process.env.API_DOMAIN,
credentials: true
},
proxy: {
"/api": {
target: process.env.API_DOMAIN,
pathRewrite: { "^/api" : "/" }
}
},
...




Nginx



Конфигурационный файл для работы сайта на веб-сервере Nginx создан и подключен:



5f90522321826692222900.png



vim /etc/nginx/sites-available/larastart.site



server {
server_name larastart.site;
root /var/www/api/public;

add_header X-Frame-Options "SAMEORIGIN";
add_header X-XSS-Protection "1; mode=block";
add_header X-Content-Type-Options "nosniff";

# Priority file extensions
index index.php index.html index.htm index.nginx-debian.html;

charset utf-8;

# Check for the existence of files matching a provided url, forward to 404 if not found
location /api {
try_files $uri $uri/ /index.php?$query_string;
}

# Serve static files directly
location ~* ^/storage/(.*)\.(jpg|jpeg|gif|bmp|png|ico)$ {
access_log off;
}

location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-VerifiedViaNginx yes;
proxy_read_timeout 300;
proxy_connect_timeout 300;
}

location /app {
proxy_pass http://127.0.0.1:6001;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-VerifiedViaNginx yes;
proxy_read_timeout 300;
proxy_connect_timeout 300;

# Specific for websockets: force the use of HTTP/1.1 and set the Upgrade header
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_cache_bypass $http_upgrade;
}

error_page 404 /index.php;

# pass PHP scripts to FastCGI server
location ~ \.php$ {
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
include fastcgi_params;
}

# deny access to .htaccess files, if Apache's document root concurs with nginx's one
location ~ /\.(?!well-known).* {
deny all;
}

listen 443 ssl; # managed by Certbot

ssl_certificate /etc/letsencrypt/live/larastart.site/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/larastart.site/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}

server {
if ($host = larastart.site) {
return 301 https://$host$request_uri;
} # managed by Certbot

listen 80;
server_name larastart.site;
return 404; # managed by Certbot
}

1 Answer

by
0 votes
5f907bab94045940607443.png
In ufw, if I'm not confused, only SSH and nginx connections are allowed. Port 6001 is bugged by php, so the connection is not allowed. 2 solutions:
1) Port 6001 through nginx ( like here )
2) Allow ufw to access php

6 Comments

tol64 , В docs They also suggest that you just specify the certificate paths in your laravel settings. And the websockets will pull everything up themselves. Or you can proxy to location in nginx instead of to the right port.
Diman Suvorkin In this configuration, there are a very large number of identical settings in different parts of the project. They need to be considered as a whole. All the environment settings files in Laravel and Nuxt are listed in the first post of the thread. You might need to change something there too (schemas, hosts, etc).

I tried changes like this:

vim /etc/supervisor/conf.d/websockets.conf

[program:websockets]
command=/usr/bin/php /var/www/api/artisan websockets:serve --host=127.0.0.1
numprocs=1
autostart=true
autorestart=true
;user=laravel-echo
supervisorctl update supervisorctl restart websockets netstat -ntlp | grep LISTEN
5f91ae0b5c78c038745242.png


You can see that the address has changed from 0.0.0.0:6001 at 127.0.0.1:6001

But POST requests now also result in an error:

5f91ae9781e7e698181893.png

//---

I'm stumped. I posted this question on two other English-language forums. There is no answer at all. )
tol64 then, most likely, php is being accessed directly, bypassing nginx. And php doesn't know anything about SSL. And yes, I just noticed - upstream websocket should lead to port 6001))
The idea is to specify the host 127.0.0.1 for websockets instead of the external 0.0.0.0 ( like here ) should only allow connections to webokets from localhost. And nginx should listen on port 6001
tol64 I've been struggling with the same problem for a long time now. I only realized that everything works fine on HTTP, but as soon as you try to switch to HTTPS, then there are such problems and without dancing with tambourines can not be solved.

I very much hope that you will publish the solution you were given.
Thank you in advance.
Diman Suvorkin I turned to the technicians at the hosting provider. They helped me set it up. All this was very close, judging by what the final settings I now see. I need to make a backup and do an experiment and try to configure everything from scratch. When I'm done, I'll post a completely finished solution.

Thank you for your participation. It was very interesting.