websocket 带有nginx的Laravel网络套接字

x759pob2  于 2022-11-11  发布在  Nginx
关注(0)|答案(1)|浏览(199)

除了 我 的 php 版本 是 php8.1.9 和 laravel8 之外 , 我 已经 按照 教程 使用 docker 配置 了 带有 websockets 的 laravel 。
我 的 nginx 容器 是 web _ dev 容器 的 反向 代理 , 并 执行 SSL 终止 。 因此 , 内部 的 进一步 通信 是 通过 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/;
    }
}

中 的 每 一 个
然后 我 有 一 个 curl 命令 :

curl -k \
    --no-buffer \
    --header "Connection: upgrade" \
    --header "Upgrade: websocket" \
    -v \
    https://mydomain.co.uk:6001/ws/app/mydomainkey

格式
以下 是 输出 :

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}"}

格式
我 认为 这 表明 端口 6001 和 SSL 配置 正确 , 并且 websocket 连接 已 建立 。
当 我 转到 websockets dashboard 的 url 并 单击 " 连接 " 时 , 我 得到
x1月 1 日

我 还 尝试 了 fetch("wss://mydomain.co.uk:6001/ws/app/mydomainkey?protocol=7&client=js&version=4.3.1&flash=false"); , 它 给出 了 不同 的 错误 :


语言
在 web _ dev 容器 上 , 我 运行 的 是 supervisor , 它 运行 php artisan websockets:serve 。 我 可以 验证 我 的 web _ dev 容器 是否 可以 连接 到 它 的 websockets 运行 服务 , 因为 我 在 php artisan tinker 中 运行 :

`event (new \App\Events\NewTrade('test'))`
=> []

格式
然后 我 检查 了 主管 日志 , 我 得到 许多 条目 :

所以 总结 一下 :

  1. nginx 服务 正常 , 因为 curl 命令 可 与 带 SSL 的 nginx 一起 正常 工作 ( 这 也 会 在 supervisor 中 生成 日志 条目 )
  2. laravel 内部 连接 正确
    1.但是 网页 浏览 器 中 的 pusher-js 却 抱怨 不 支持 wss 方案 , 并且 websocket 连接 失败 。nginx/1.21.5 语言 版本
    1.我 甚至 还 没有 使用 Echo 。 Echo 使用 pusher-js , 而 Jmeter 板 是 用 pusher-js 实现 的 。 所以 如果 Jmeter 板 不 工作 , 我 的 Echo 也 不会 工作 。
    1.我 现在 已经 在 package.json 中将 我 的 pusher 降级 为 4.3.1 , 但 这 没有 任何 作用 , 因为 该 版本 是 硬 编码 在 Jmeter 板 中 的 ( 尽管 也 是 4.3 ) 。


语言
有 什么 想法 吗 ?
1.我 试图 修改 Jmeter 板 拉 一 个 不同 的 版本 https://cdnjs.cloudflare.com/ajax/libs/pusher/6.0.3/pusher.js , 这 没有 任何 区别 。

  1. nginx 可以 支持 wss 而 不是 http 吗 ? 我 只 看到 过 使用 http 的 configs 。 使用 wss 的 configs :抛出 一 个 错误 。
    所以 我 没 办法 了 。
    以下 是 我 的 配置 文件 :
    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.*/

格式
相关 问题 :

hsvhsicv

hsvhsicv1#

"我是怎么发现的"
我首先尝试为内部通信设置SSL证书,尽管nginx正在终止(我不得不尝试)-但随后curl命令中断,我无法连接到我的websockets,除非我删除我的SSL证书(正在获得坏网关)。
所以我最终得到了这些:

'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'),
        'encrypted' => false,
        'host' => "127.0.0.1",
        'port' => 6001,
        'useTLS' => false,
        'scheme' => 'http',
    ],
],

并在config/websockets.php中找到

'apps' => [
    [
        'id' => env('PUSHER_APP_ID'),
        'name' => env('APP_NAME'),
        'key' => env('PUSHER_APP_KEY'),
        'secret' => env('PUSHER_APP_SECRET'),
        'path' => "/ws",    //<-- important for nginx path detection
        'capacity' => null,
        'enable_client_messages' => false,
        'enable_statistics' => true,
    ],
],
'ssl' => [
    'local_cert' => null,
    'local_pk' => null,
    'passphrase' => null,
],

然后我注意到一件关于日志的事情。当我在浏览器中得到WebSocket错误时,我也在为我的supervisor/websocket.log接收一个新的日志条目。
我试图删除'path' => "/ws",我收到了同样的浏览器错误,但没有日志条目。
这给了我第一个提示,当有总比没有好。我需要坚持任何设置,不会打破这个日志记录功能。
然后我发现,当我从nginx.conf中删除这些行时,它开始全部工作,令人震惊!!

proxy_set_header    Sec-WebSocket-Key       'SGVsbG8sIHdvcmxkIQAAAA==';
    proxy_set_header    Sec-WebSocket-Version   '13';

最初我添加这些命令是为了简化curl命令,但我不知道这会破坏浏览器的websocket,所以现在测试的curl看起来像这样:

curl -k \
    --no-buffer \
    --header "Connection: upgrade" \
    --header "Upgrade: websocket" \
    --header "Sec-WebSocket-Key: SGVsbG8sIHdvcmxkIQAAAA==" \ //<-- this is random you can use it
    --header "Sec-WebSocket-Version: 13" \
    -v \
    https://mydomain.co.uk:6001/ws/app/mydomainkey

相关问题