You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel-Echo客户端无法响应服务端事件排查求助

Laravel广播事件无法在React+Electron客户端接收(Docker环境)

我正在搭建基于PHP8.2、Laravel10、WebSockets与Redis的Docker环境,已配置好镜像并搭配Caddy代理,用Horizon调试广播功能。服务端事件能在laravel-echo-server调试控制台和Laravel Horizon正常显示,无报错,但React+Electron客户端已安装socket.io-client和laravel-echo并完成配置,能看到WebSocket的ping/pong请求,却接收不到服务端触发的TranslationEvent事件。调整通道名称、事件监听方式都没用,之前用Pusher也遇到同样问题,怀疑是Docker配置或其他环节出错。

docker-compose.yml

services:
  ### workspace ##################################
  workspace:
    build:
      context: ./workspace
      args:
        - TZ=${WORKSPACE_TIMEZONE}
        - NODE_VERSION=${WORKSPACE_NODE_VERSION}
        - YARN_VERSION=${WORKSPACE_YARN_VERSION}
        - APP_CODE_PATH=${APP_CODE_PATH_CONTAINER}
    environment:
      - APP_CODE_PATH=${APP_CODE_PATH_CONTAINER}
    volumes:
      - ${APP_CODE_PATH_HOST}:${APP_CODE_PATH_CONTAINER}
    tty: true
    networks:
      - frontend
      - backend
  
  ### php-fpm ##############################################
  php-fpm:
    build:
      context: ./php-fpm
      args:
        - APP_CODE_PATH=${APP_CODE_PATH_CONTAINER}
    restart: unless-stopped
    volumes:
      - ${APP_CODE_PATH_HOST}:${APP_CODE_PATH_CONTAINER}
    expose:
      - "9000"
    depends_on:
      - workspace
      - db
      - redis
      - laravel-echo-server
    networks:
      - backend

  ### caddy ###############################################
  caddy:
    image: caddy:2.2.1
    environment:
      - CADDY_HOST_LABEL=${CADDY_HOST_LABEL}
      - APP_CODE_PATH=${APP_CODE_PATH_CONTAINER}
    restart: unless-stopped
    volumes:
      - ${APP_CODE_PATH_HOST}:${APP_CODE_PATH_CONTAINER}
      - caddy_data:/data
      - caddy_config:/config
      - ./caddy/Caddyfile:/etc/caddy/Caddyfile
    ports:
      - "${CADDY_HOST_HTTP_PORT}:80"
      - "${CADDY_HOST_HTTPS_PORT}:443"
    depends_on:
      - php-fpm
    networks:
      - frontend
      - backend

  ### db ##################################################
  db:
    image: mariadb:latest
    build:
      context: ./db
    environment:
      - MYSQL_DATABASE=${DB_DATABASE}
      - MYSQL_USER=${DB_USER}
      - MYSQL_PASSWORD=${DB_PASSWORD}
      - MYSQL_ROOT_PASSWORD=${DB_ROOT_PASSWORD}
      - TZ=${WORKSPACE_TIMEZONE}
    restart: unless-stopped
    volumes:
      - ${DATA_PATH_HOST}/db:/var/lib/mysql
    expose:
      - "3306"
    ports:
      - "${DB_PORT}:3306"
    networks:
      - backend

  ### redis ###############################################
  redis:
    build: ./redis
    restart: unless-stopped
    volumes:
      - ${DATA_PATH_HOST}/redis:/data
    expose:
      - "6379"
    ports:
      - "${REDIS_PORT}:6379"
    networks:
      - backend

  ### websockets ##########################################
  laravel-echo-server:
    image: oanhnn/laravel-echo-server:latest
    depends_on:
      - redis
    environment:
      LARAVEL_ECHO_SERVER_AUTH_HOST: http://example.com
      LARAVEL_ECHO_SERVER_DEBUG:     'true'
      LARAVEL_ECHO_SERVER_DB:        redis
      REDIS_HOST:     redis
      REDIS_PORT:     6379
      REDIS_PREFIX:   ""
      REDIS_DB:       0
    expose:
      - "6001"
    ports:
     - 6001:6001
    restart: unless-stopped
    networks:
      - backend

  ### horizon #############################################
  horizon:
    build:
      context: ./horizon
      args:
        - APP_CODE_PATH=${APP_CODE_PATH_CONTAINER}
    restart: unless-stopped
    volumes:
      - ${APP_CODE_PATH_HOST}:${APP_CODE_PATH_CONTAINER}
    depends_on:
      - redis
    networks:
      - backend

version: '3'

networks:
  frontend:
  backend:

volumes:
  mysql:
  redis:
  caddy_data:
  caddy_config:

客户端配置

import Echo from 'laravel-echo';
window.io = require('socket.io-client');
if (typeof io !== 'undefined') {
  window.Echo = new Echo({
    broadcaster: 'socket.io',
    host: window.location.hostname + ':6001',
  });
} else {
  console.log("IO ERROR")
}

window.Echo.channel(`laravel_database_translation.1`)
.listen('.App\Events\TranslationEvent', (e) => {
  console.log(e)
})

Laravel事件代码

<?php

namespace App\Events;

use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;

class TranslationEvent implements ShouldBroadcast
{
    use Dispatchable, InteractsWithSockets, SerializesModels, Queueable;

    /**
     * Create a new event instance.
     */
    public function __construct(public $id, public $message)
    {
        
    }

    /**
     * Get the channels the event should broadcast on.
     *
     * @return Channel
     */
    public function broadcastOn()
    {
        return new Channel('translation.'.$this->id);
    }
}

解决步骤

1. 修正通道名称匹配问题

Laravel Echo会自动为Redis广播通道添加laravel_database_前缀,无需手动在客户端监听时追加。当前客户端监听的laravel_database_translation.1是错误的,应直接使用事件中定义的通道名:

// 替换原通道监听代码
window.Echo.channel('translation.1')
.listen(/* ... */)

2. 修正事件监听格式

客户端监听事件存在两处错误:

  • 事件名前的多余点号需移除
  • JavaScript字符串中的反斜杠必须双转义

修正后的监听代码:

window.Echo.channel('translation.1')
.listen('App\\Events\\TranslationEvent', (e) => {
  console.log(e)
})

更简洁的方案是在事件类中定义广播别名,避免转义问题:

// 在TranslationEvent类中添加以下方法
public function broadcastAs()
{
    return 'translation-event';
}

然后客户端直接监听别名:

window.Echo.channel('translation.1')
.listen('translation-event', (e) => {
  console.log(e)
})

3. 修正laravel-echo-server的认证主机配置

docker-compose中laravel-echo-server的LARAVEL_ECHO_SERVER_AUTH_HOST设置为http://example.com,与实际开发环境不符,会导致认证失败或事件推送异常。修改为你的实际服务端地址,比如本地开发用:

LARAVEL_ECHO_SERVER_AUTH_HOST: http://localhost

或你配置的自定义域名。

4. 检查Socket.io版本兼容性

laravel-echo-server通常依赖Socket.io 2.x版本,若客户端安装的是最新的Socket.io-client 4.x,会出现版本不兼容问题。执行以下命令安装兼容版本:

npm uninstall socket.io-client
npm install socket.io-client@2.4.0

5. 验证队列与Horizon运行状态

虽然Horizon显示事件正常,但需确认:

  • config/broadcasting.php中Redis驱动的队列配置正确,队列连接指向Redis
  • Horizon的Worker正在正常运行,没有被阻塞或报错

内容的提问来源于stack exchange,提问作者Dambas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 01:33:11