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

Laravel Reverb与Flutter聊天应用无法接收消息问题求助

问题描述

我用Flutter的dart_pusher_channels包搭配Laravel Reverb开发聊天应用,已经按Laravel文档配置好Sanctum认证,创建了MessageSent广播事件,设置了channels.php路由,修改了bootstrap/app.php的广播配置。消息存入数据库后执行broadcast(new MessageSent($message))广播,后端(8000端口)、Reverb服务(8080端口)和队列都已启动,但Flutter前端收不到消息。试过ShouldBroadcastNow、Pusher驱动以及其他Flutter WebSocket包,都没解决问题。


Laravel 事件代码

class MessageSent implements ShouldBroadcast
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    public $message;
    public function __construct(Messages $message)
    {
        $this->message = $message;
    }

    public function broadcastOn(): array
    {
        $channels = [];

        $participants = ChatParticipants::where('chat_id', $this->message->chat_id)->pluck('user_id');

        foreach ($participants as $userId) {
            $channels[] = new PrivateChannel('chat.' . $userId);
        }
        return $channels;
    }
    public function broadcastAs(): string
    {
        return 'message.sent';
    }
}

Channels.php 路由配置

Broadcast::channel('chat.{id}', function (User $user, $id) {
    return $user->id === $id;
});

Bootstrap/app.php 配置

return Application::configure(basePath: dirname(__DIR__))
    ->withRouting(
        web: __DIR__.'/../routes/web.php',
        api: __DIR__.'/../routes/api.php',
        commands: __DIR__.'/../routes/console.php',
        // channels: __DIR__.'/../routes/channels.php',
        health: '/up',
    )
    ->withBroadcasting(
        channels: __DIR__.'/../routes/channels.php',
        attributes: ['prefix' => 'api', 'middleware' => ['auth:sanctum']],
    )
    ->withMiddleware(function (Middleware $middleware) {
        //
    })
    ->withExceptions(function (Exceptions $exceptions) {
        //
    })->create();

Flutter 连接代码

Future<void> dartconnect() async {
    try {
      final auth = Provider.of<AuthState>(context, listen: false);

      const hostOptions = PusherChannelsOptions.fromHost(
        scheme: 'ws',
        host: '*.*.*.*',
        key: 'reverb_key',
        shouldSupplyMetadataQueries: true,
        metadata: PusherChannelsOptionsMetadata.byDefault(),
        port: 8080,
      );

      final client = PusherChannelsClient.websocket(
          options: hostOptions,
          connectionErrorHandler: (exception, trace, refresh) {
            refresh();
          });

      final private = client.privateChannel(
        'chat.${auth.user!.id}',
        authorizationDelegate:
            EndpointAuthorizableChannelTokenAuthorizationDelegate
                .forPrivateChannel(
          authorizationEndpoint: Uri.parse('$domain/api/broadcasting/auth'),
          headers: {
            'Authorization': 'Bearer ${auth.loginToken}',
          },
        ),
      );

      StreamSubscription<ChannelReadEvent> privateSubscription =
          private.bind('message.sent').listen((event) {
        print('Private event received:${event.data} ');
      });

      client.onConnectionEstablished.listen((s) {
        print('Connection established');
        private.subscribe();
      });

      await client.connect();
  
    } catch (e) {
      
    }
  }

排查建议

  • 检查日志定位问题:查看Reverb日志(storage/logs/reverb.log)和Laravel日志(storage/logs/laravel.log),确认广播事件是否被推送、频道授权是否成功、队列任务是否正常执行。
  • 验证频道授权:手动调用/api/broadcasting/auth接口,传入正确的Authorization头和channel_name=private-chat.{userId}、socket_id参数,检查返回是否为200和有效授权数据。
  • 确认频道与事件名称匹配:Reverb会自动给私有频道添加private-前缀,确保事件broadcastOn返回的chat.{userId}对应前端订阅的private-chat.{userId};同时确认bind的事件名和broadcastAs()返回的完全一致。
  • 调试Flutter客户端:在connectionErrorHandler中打印异常信息,确认连接/授权是否失败;添加日志检查onConnectionEstablished是否触发、private.subscribe()是否执行成功。
  • 核对环境配置:确保.env中BROADCAST_DRIVER=reverb,REVERB_APP_KEY等配置和Flutter端的key一致;检查服务器防火墙是否开放8080端口,客户端能正常访问Reverb服务。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 09:25:20