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

PHP Ratchet Push无法接收通知问题排查求助

排查Ratchet WebSocket推送前端收不到消息的问题

我来帮你梳理下几个最可能导致这个问题的方向,你可以逐一排查:

1. 前端WebSocket连接与消息监听是否正常

  • 先检查page.html里的WebSocket连接地址是否正确,比如Ratchet服务端监听的是8080端口的话,连接应该是new WebSocket('ws://localhost:8080'),别写错端口或域名。
  • 打开浏览器控制台(F12),切换到Network标签,筛选WS类型,看WebSocket请求的状态是不是101 Switching Protocols。如果连接失败,控制台会直接抛出错误(比如连接超时、拒绝),这时候要确认服务端确实在运行并监听对应端口。
  • 务必确保前端正确监听了onmessage事件,比如:
    const conn = new WebSocket('ws://localhost:8080');
    // 监听连接成功
    conn.onopen = () => console.log('WebSocket连接成功');
    // 监听消息
    conn.onmessage = (e) => {
        console.log('收到推送:', e.data);
        // 这里要写你自己的消息展示逻辑
    };
    // 监听错误
    conn.onerror = (err) => console.error('WebSocket错误:', err);
    
    很多时候收不到消息只是因为没写onmessage或者写错了方法名。

2. 服务端Pusher类的客户端连接管理是否正确

  • 检查bin/push-server.php里是否正确把Pusher实例绑定到Ratchet服务,比如:
    use Ratchet\Server\IoServer;
    use Ratchet\Http\HttpServer;
    use Ratchet\WebSocket\WsServer;
    use YourNamespace\Pusher;
    
    require dirname(__DIR__) . '/vendor/autoload.php';
    
    $pusher = new Pusher();
    $server = IoServer::factory(
        new HttpServer(
            new WsServer($pusher)
        ),
        8080 // 确保这个端口和前端连接的一致
    );
    
    echo "WebSocket服务启动,监听端口8080\n";
    $server->run();
    
  • 再看src/Pusher.php是否正确实现MessageComponentInterface,并且在onOpen时把客户端连接存入存储对象:
    use Ratchet\MessageComponentInterface;
    use Ratchet\ConnectionInterface;
    
    class Pusher implements MessageComponentInterface {
        protected $clients;
    
        public function __construct() {
            $this->clients = new \SplObjectStorage();
        }
    
        public function onOpen(ConnectionInterface $conn) {
            // 把新连接加入客户端列表
            $this->clients->attach($conn);
            echo "新客户端连接:{$conn->resourceId}\n";
        }
    
        // 确保实现了onMessage、onClose、onError方法
        public function onMessage(ConnectionInterface $from, $msg) {}
        public function onClose(ConnectionInterface $conn) {
            $this->clients->detach($conn);
        }
        public function onError(ConnectionInterface $conn, \Exception $e) {}
    
        // 推送方法,遍历客户端发送消息
        public function pushMessage($message) {
            foreach ($this->clients as $client) {
                $client->send($message);
            }
        }
    }
    
    如果没有在onOpen时保存连接,推送时就找不到要发送的客户端。

3. post.php的推送触发逻辑是否正确

  • 重点注意:Ratchet服务是独立运行的进程,post.php作为Web请求脚本,不能直接实例化Pusher调用推送方法(因为这是两个完全独立的进程,Web进程里的Pusher没有客户端连接)。
  • 官方文档推荐用Redis做中间件来触发推送:服务端监听Redis频道,post.php往该频道发送消息,服务端收到后再推送给客户端。你要确认:
    1. 服务端是否正确绑定了Redis订阅,比如在bin/push-server.php里添加:
      $loop = React\EventLoop\Factory::create();
      $redis = new React\Redis\Client($loop, ['host' => '127.0.0.1', 'port' => 6379]);
      $redis->subscribe('push_notifications', function ($message) use ($pusher) {
          $pusher->pushMessage($message);
      });
      $server = IoServer::factory(new HttpServer(new WsServer($pusher)), 8080, '0.0.0.0');
      $server->run();
      
    2. post.php是否正确往Redis频道发送消息:
      $redis = new Redis();
      $redis->connect('127.0.0.1', 6379);
      $redis->publish('push_notifications', '你要推送的内容');
      
    如果跳过了Redis中间件直接调用,肯定推不到客户端。

4. Windows环境的特殊限制

  • 检查Windows防火墙是否阻止了WebSocket端口(比如8080),可以临时关闭防火墙测试,或者在防火墙里添加允许该端口的入站规则。
  • 确认PHP的sockets扩展是否启用:打开命令行输入php -m,看输出里有没有sockets,如果没有,打开php.ini去掉extension=sockets前面的注释,重启服务。
  • 如果用了Redis,确保Redis服务在Windows上正常运行(可以用redis-cli ping测试,返回PONG就是正常)。

5. 跨域问题(如果前端是HTTP访问)

  • 如果你的page.html是通过http://localhost(80端口)打开,而WebSocket是ws://localhost:8080,端口不同属于跨域场景。虽然WebSocket默认允许跨域,但有些浏览器可能有严格限制,你可以在服务端添加跨域允许:
    $httpServer = new HttpServer(new WsServer($pusher));
    // 允许所有来源,也可以指定你的前端域名
    $httpServer->setOriginCheck(function ($origin) {
        return true;
    });
    

如果排查完这些还是没解决,可以把关键代码片段(比如Pusher类的推送方法、post.php的触发逻辑、前端连接代码)贴出来,这样能更精准定位问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 10:42:40