Soketi与Echo的SSL连接失败及私有频道授权问题
Laravel + Soketi + Echo 连接故障排查
环境配置
- Forge
- Nginx
- Soketi
- Echo
- Laravel
- Sanctum
问题现象
- SSL连接异常,报错:
WebSocket connection to 'wss://IP:6002/app/payload' failed: - 使用WS未加密连接时,报错:
Connection is not authorized
初步处理思路
- 强制使用WSS加密连接
- 将请求发送到6002端口
- 通过Nginx反向代理转发至6001端口
自我排查方向
- Nginx配置可能存在错误
- 可能需要调整连接端口
补充信息
- 6001、6002端口已开放
相关配置文件内容
.env 配置
PUSHER_HOST=IP PUSHER_APP_ID=APPID PUSHER_APP_KEY=KEY PUSHER_APP_SECRET=SECRET PUSHER_APP_PORT=6002 PUSHER_APP_ENCRYPTED=true PUSHER_APP_SCHEMA=https PUSHER_APP_CLUSTER="eu-central-1" MIX_PUSHER_HOST="${PUSHER_HOST}" MIX_PUSHER_APP_PORT="${PUSHER_APP_PORT}" MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}" MIX_PUSHER_APP_ENCRYPTED="${PUSHER_APP_ENCRYPTED}" MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}" MIX_PUSHER_PORT="${PUSHER_APP_PORT}"
auth.php 认证配置
'defaults' => array( 'guard' => 'web', 'passwords' => 'users', ), 'guards' => array( 'web' => array( 'driver' => 'session', 'provider' => 'users', ), 'api' => array( 'driver' => 'token', 'provider' => 'users', 'hash' => false, ), ),
BroadcastServiceProvider 广播服务提供者
public function boot() { Broadcast::routes(['middleware' => ['auth:api']]); require base_path('routes/channels.php'); }
Echo 前端配置
window.Echo = new Echo({ broadcaster: 'pusher', host: `${process.env.MIX_APP_HOST}:${process.env.MIX_PUSHER_APP_PORT}`, key: process.env.MIX_PUSHER_APP_KEY, wsHost: process.env.MIX_PUSHER_HOST, wsPort: process.env.MIX_PUSHER_PORT, wssPort: "6002", forceTLS: true, enabledTransports: ['ws', 'wss'], encrypted: process.env.MIX_PUSHER_APP_ENCRYPTED, reconnection: true, enableLogging: true, disableStats: true, authorizer: (channel, options) => { return { authorize: (socketId, callback) => { console.log("Requested something") axios.post('/api/broadcasting/auth', { socket_id: socketId, channel_name: channel.name }) .then(response => { console.log(response) callback(false, response); }) .catch(error => { callback(true, error); }); } }; }, });
api.php 路由配置
Route::prefix('broadcasting')->controller(BroadcastingController::class)->group(function () { Route::post('/auth', 'validateWebsocket'); });
BroadcastingController 广播认证控制器
public function validateWebsocket(Request $request) { Log::debug("socket_id: " . $request->get("socket_id") . ", channel_name: " . $request->get("channel_name")); return response()->json([], 200); }
Channels.php 频道授权配置
Broadcast::channel('users.{userId}', function ($user, $userId) { Log::debug("Requesting"); return empty($user) === false && $user->id == $userId; });
Nginx 反向代理配置
server { listen 6002 ssl http2; listen [::]:6002 ssl http2; server_name WEBSITE; server_tokens off; # FORGE SSL (DO NOT REMOVE!) ssl_certificate /etc/nginx/ssl/WEBSITE/PATH/server.crt; ssl_certificate_key /etc/nginx/ssl/WEBSITE/PATH/server.key; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers CIPHER; ssl_prefer_server_ciphers off; ssl_dhparam /etc/nginx/dhparams.pem; add_header X-Frame-Options "SAMEORIGIN"; add_header X-XSS-Protection "1; mode=block"; add_header X-Content-Type-Options "nosniff"; location / { proxy_pass http://127.0.0.1:6001; 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_set_header Host $host; proxy_cache_bypass $http_upgrade; } access_log /home/forge/WEBSITE/so_ac.log; error_log /home/forge/WEBSITE/so_er.log error; }
Soketi config.json 配置
{ "debug": true, "port": 6002, "appManager.array.apps": [ { "id": "ID", "key": "KEY", "secret": "SECRET" } ], "ssl": { "certPath": "PATH", "keyPath": "PATH" } }
内容的提问来源于stack exchange,提问作者Jaeger
相关产品推荐
相关产品推荐

