软件:
在websockets.php(complete file)中,我设置了local_cert
和local_pk
以及证书。如果我将此选项留空,我什至无法连接。我还将verify_peer
设置为false
,因为如果不这样做,我也无法连接。
broadcasting.php:
'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'),
'host' => '127.0.0.1',
'port' => 6001,
'scheme' => 'https',
'curl_options' => [
CURLOPT_SSL_VERIFYHOST => 0,
CURLOPT_SSL_VERIFYPEER => 0,
]
],
],
如果我摆脱了curl选项,我将得到一个空的Broadcast异常like described here。
bootstrap.js:
window.Pusher = require('pusher-js');
window.Echo = new Echo({
broadcaster: 'pusher',
key: '7d23096ae0ab2d02d220',
wsHost: window.location.hostname,
wsPort: 6001,
wssPort: 6001,
encrypted: true,
disableStats: true,
auth: {
headers: {
'X-CSRF-TOKEN': window.App.csrfToken,
},
},
})
这是我在运行php artisan websockets:serve
后从日志中得到的所有信息:
New connection opened for app key 7d23096ae0ab2d02d220.
Connection id 49092664.114416323 sending message {"event":"pusher:connection_established","data":"{\"socket_id\":\"49092664.114416323\",\"activity_timeout\":30}"}
我应该得到的是有关侦听/加入频道以及发送消息等消息,但是目前所有这些都无法正常工作。我有类似的东西:
Echo.private('notifications.' + this.user.id)
.listen('UserNotificationSent', (e) => {
console.log(e)
})
事件:例如UserNotificationSent.php。
当然,在内部,我还进行了其他所有设置:带有auth的通道等。所有内容均在较低Laravel版本(5.4)的计算机上本地运行。但是我最近更新到5.8并部署到服务器,现在我为此感到困惑。
重要更新
这实际上不是由于部署造成的,我在本地设置中也遇到了同样的问题。有趣的是,通过Echo.channel()
收听频道有效,但是.private()
无效。在Github(上面的链接)上,我遇到了一个完全相同的问题的人。我们尚未找到解决方案。
答案 0 :(得分:0)
发生这种情况是因为端口6001在实时服务器上的nginx中已保留(底部有说明)。我需要在nginx上使用反向代理才能使其正常工作-并将端口6002用于实时服务器中的websocket。
在 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服务器配置尽可能简洁明了。
这也使通过“加密”的自动化变得更加容易,因为已经有一些实现可以管理Nginx中的证书配置并在需要时重新加载它们。-Source - 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,
]
和 broadcasting.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'
],
],
这是我的整个工作周期,这使其得以发挥作用。希望对您有所帮助。
“但是为什么端口6000、6002和433真是一团糟!”
我听到了!让我解释一下,希望以后一切都会有意义。
这就是问题,一次只能在一个应用程序上打开服务器上的端口(从技术上讲,这不是正确的,但让我们在此保持简单)。因此,如果我们让NGINX在端口6001上侦听,我们将无法在端口6001上也启动我们的websockets服务器,因为它将与NGINX冲突,反之亦然,因此我们让NGINX在端口6002上侦听并使其代理(NGINX是反向代理)毕竟)通过纯http到端口6001(websockets服务器)的所有流量。剥离SSL,因此websockets服务器无需知道如何处理SSL。
因此NGINX将处理所有SSL魔术,并将纯HTTP流量转发到Websockets服务器正在侦听请求的服务器上的端口6001。
之所以没有在websockets.php配置中配置任何SSL,而是在broadcast.php中将方案定义为http并使用端口6001的原因,是为了绕过NGINX并直接与本地的websockets服务器通信,而无需SSL,速度更快(更易于配置和维护)。
答案 1 :(得分:0)
我发现了问题。
我在web.php
中有这个东西:
Route::post('/broadcasting/auth', function (Illuminate\Http\Request $req) {
if ($req->channel_name == 'users') {
return Broadcast::auth($req);
}
});
我不完全记得为什么以及何时添加它,但这可能来自here。由于某种原因,这不会产生任何错误。无论如何,我摆脱了这一点,现在它就像一种魅力一样工作。
答案 2 :(得分:-3)
在事件中使用broadcastAs()方法
public function broadcastAs()
{
return 'UserNotificationSent';
}
这样听。
.listen('.UserNotificationSent', function (e) {
....
});
在UserNotificationSent事件之前放置点(。)来监听