发生这种情况是因为在实时服务器上的 nginx 中保留了端口 6001(底部有说明)。我需要在 nginx 上使用反向代理来使其工作 - 并使用端口 6002 用于实时服务器中的 websockets。
在nginx 中(根据要求,我添加了完整的 nginx 代码):
server {
#The nginx domain configurations
root /var/www/laravel/public;
index index.html index.htm index.php index.nginx-debian.html;
server_name example.com www.example.com;
#WHAT YOU NEED IS FROM HERE...
location / {
try_files $uri $uri/ /index.php?$query_string;
# "But why port 6000, 6002 and 433? Scroll at the bottom"
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 https;
proxy_set_header X-VerifiedViaNginx yes;
proxy_read_timeout 60;
proxy_connect_timeout 60;
proxy_redirect off;
# Specific for websockets: force the use of HTTP/1.1 and set the Upgrade header
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
#..UNTIL HERE - The rest are classic nginx config and certbot
#The default Laravel nginx config
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/run/php/php7.2-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
#SSL by certbot
listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl on;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/example.com/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
ssl_session_cache shared:SSL:30m;
ssl_protocols TLSv1.1 TLSv1.2;
# Diffie Hellmann performance improvements
ssl_ecdh_curve secp384r1;
}
通过 TLS 连接到您的域的所有内容都将以纯文本形式代理到端口 6001 上的本地服务。这会将所有 TLS(和证书管理)卸载到 Nginx,使您的 websocket 服务器配置尽可能干净和简单。
这也使通过 Let's Encrypt 的自动化变得更加容易,因为已经有一些实现可以管理 Nginx 中的证书配置并在需要时重新加载它们。-资料来源 - Mattias Geniar
回声设置:
let isProduction = process.env.MIX_WS_CONNECT_PRODUCTION === 'true';
Vue.prototype.Echo = new LaravelEcho({
broadcaster: 'pusher',
key: process.env.MIX_PUSHER_APP_KEY,
wssHost: window.location.hostname,
wssPort: isProduction ? 6002 : 6001,
wsHost: window.location.hostname,
wsPort: isProduction ? 6002 : 6001,
disableStats: false,
encrypted: isProduction,
enabledTransports: ['ws', 'wss'],
disabledTransports: ['sockjs', 'xhr_polling', 'xhr_streaming']
});
在websockets.php中
'apps' => [
[
'id' => env('MIX_PUSHER_APP_ID'),
'name' => env('APP_NAME'),
'key' => env('MIX_PUSHER_APP_KEY'),
'secret' => env('MIX_PUSHER_APP_SECRET'),
'enable_client_messages' => false,
'enable_statistics' => true,
],
],
// I kept them null but I use LetsEncrypt for SSL certs too.
'ssl' => [
'local_cert' => null,
'local_pk' => null,
'passphrase' => null,
]
和广播.php
'pusher' => [
'driver' => 'pusher',
'key' => env('MIX_PUSHER_APP_KEY'),
'secret' => env('MIX_PUSHER_APP_SECRET'),
'app_id' => env('MIX_PUSHER_APP_ID'),
'options' => [
'cluster' => env('MIX_PUSHER_APP_CLUSTER'),
'encrypted' => env('MIX_WS_CONNECT_PRODUCTION'),
'host' => '127.0.0.1',
'port' => env('MIX_WS_CONNECT_PRODUCTION') ? 6002 : 6001,
'scheme' => 'http'
],
],
这是我让它工作的完整周期。希望能帮助到你。
引用Alex Bouma 的解释:
“可是为什么是6000、6002和433端口,什么乱七八糟的!?”
我听到了!让我解释一下,希望以后一切都有意义。
事情是这样的,在您的服务器上打开一个端口一次只能由一个应用程序完成(从技术上讲,这不是真的,但让我们在这里保持简单)。因此,如果我们让 NGINX 在端口 6001 上侦听,我们也无法在端口 6001 上启动我们的 websockets 服务器,因为它会与 NGINX 冲突,反之亦然,因此我们让 NGINX 在端口 6002 上侦听并让它代理(NGINX 是反向代理毕竟)所有通过普通 http 到端口 6001(websockets 服务器)的流量。剥离 SSL,因此 websockets 服务器无需知道如何处理 SSL。
因此,NGINX 将处理所有 SSL 魔法,并将普通 http 的流量转发到您的服务器上的端口 6001,websockets 服务器正在该端口监听请求。
我们没有在 websockets.php 配置中配置任何 SSL 并且我们在 broadcasting.php 中将方案定义为 http 并使用端口 6001 的原因是绕过 NGINX 并直接在本地与 websockets 服务器通信,而不需要更快(更容易)的 SSL配置和维护)。