因為手頭一個 ws 的專案必須 PWA 化,所以對應的 Websockets 也要使用 SSL,由於 Laravel-Websockets 文件中關於如何支援 SSL 寫得不是很詳細,把 issue 裡面相關的問題都看了一遍最後才解決了,記錄一下
生成證照(*.example.com)
我使用的是 Let’s Encrypt 的免費萬用字元證照,生成步驟如下
# 先確保你的機器上裝了 git cd /opt git clone https://github.com/certbot/certbot.git cd certbot ./certbot-auto certonly --manual --preferred-challenges=dns --email my@email.com --server https://acme-v02.api.letsencrypt.org/directory --agree-tos -d *.example.com -d example.com
然後按照提示為你的域名新增一個
TXT
的解析,用以驗證你對域名的所有權,稍等片刻,讓 DNS 快取更新後驗證成功即可生成 SSL 證照。修改配置檔案
config/broadcasting.php
<?php $ssl_pusher_config = [ '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' => true, 'host' => '127.0.0.1', 'port' => 6001, 'scheme' => 'https', 'curl_options' => [ CURLOPT_SSL_VERIFYHOST => 0, CURLOPT_SSL_VERIFYPEER => 0, ] ] ]; $not_ssl_pusher_config = [ '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' => true, 'host' => '127.0.0.1', 'port' => 6001, 'scheme' => 'http' ] ]; return [ ... 'connections' => [ // 本地開發環境中不使用 SSL 'pusher' => env('APP_ENV') === 'local' ? $not_ssl_pusher_config : $ssl_pusher_config, ... ], ];
config/websockets.php
... 'ssl' => [ 'local_cert' => env('SSL_CERT', null), 'local_pk' => env('SSL_PK', null), 'passphrase' => env('JWT_SECRET', null), // 這個是可選項,作用類似於 JWT_SECRET, 用於加密 'verify_peer' => false, ], ...
.env
相關配置BROADCAST_DRIVER=pusher ... PUSHER_APP_ID=appid PUSHER_APP_KEY=websocketkey PUSHER_APP_SECRET=secret ... SSL_CERT=/etc/letsencrypt/live/example.com/fullchain.pem SSL_PK=/etc/letsencrypt/live/example.com/privkey.pem
前端呼叫
import Echo from 'laravel-echo'; let echor = new Echo({ broadcaster: 'pusher', key: process.env.MIX_PUSHER_APP_KEY, wsHost: window.location.hostname, wsPort: 6001, wssPort: 6001, disableStats: true, enabledTransports: ['ws', 'wss'], // 我用的是 jwt 進行驗證的,如果你用的 session,請忽略此 auth: { headers: { Authorization: `${store.state.auth.token.token_type} ${store.state.auth.token.access_token}` } } }); export default echor;
部署
開放 6001 埠
sudo ufw allow 6001
讓 websockets 持續執行,首先安裝
supervisor
apt install supervisor
建立一個新的
supervisor
程式# 建立一個 websockets.conf touch /etc/supervisor/conf.d/websockets.conf # 填寫如下 [program:websockets] command=/usr/bin/php /your-project-location/artisan websockets:serve numprocs=1 autostart=true autorestart=true user=sudo-www # 載入 websockets.conf supervisorctl update supervisorctl start websockets # 驗證狀態 supervisorctl status
完成~
本作品採用《CC 協議》,轉載必須註明作者和本文連結