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
相关产品推荐
相关产品推荐

