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

如何在Flutter中监听Laravel WebSockets的MessageSent事件

解决Laravel WebSockets(无Pusher)与Flutter端事件监听失效问题

一、先确认Laravel端核心配置是否到位

  • 确保MessageSent事件类实现ShouldBroadcast接口,且broadcastOn()返回正确频道(公共频道用BroadcastChannel('xxx'),私有频道用PrivateChannel('xxx'))。如果自定义了事件名称(通过broadcastAs()方法),Flutter端必须用这个自定义名称监听,不能用类名。
  • 检查.env配置:
    BROADCAST_DRIVER=pusher
    PUSHER_APP_ID=your_app_id
    PUSHER_APP_KEY=your_app_key
    PUSHER_APP_SECRET=your_app_secret
    PUSHER_HOST=localhost
    PUSHER_PORT=6001
    PUSHER_SCHEME=http
    
    (虽然不用Pusher官方服务,但Laravel WebSockets依赖Pusher驱动的配置逻辑)

二、Flutter端监听逻辑修正

用socket_io_client包的正确写法

Laravel WebSockets的Socket.IO端点是/socket.io,连接和订阅要严格对应频道规则:

import 'package:socket_io_client/socket_io_client.dart' as IO;

void initSocket() {
  final socket = IO.io('http://你的Laravel地址:6001', IO.OptionBuilder()
      .setTransports(['websocket']) // 强制用WebSocket传输
      .setExtraHeaders({'Authorization': 'Bearer 你的用户Token'}) // 私有频道必须带认证
      .enableDebug(true) // 开启调试日志,方便排查
      .build());

  socket.onConnect((_) {
    print('连接成功');
    // 订阅频道:公共频道直接写名称,私有频道要加前缀'private-'
    socket.emit('subscribe', {'channel': 'chat'});
  });

  // 监听事件:如果事件用了broadcastAs('message_sent'),这里就写'message_sent',否则写'MessageSent'
  socket.on('MessageSent', (data) {
    print('收到事件数据: $data');
  });

  socket.onConnectError((err) => print('连接错误: $err'));
  socket.onDisconnect((_) => print('断开连接'));
}

用web_socket_channel包的正确写法

Laravel WebSockets的原生WebSocket端点需要带上AppKey和协议参数,订阅频道要发送特定格式的JSON消息:

import 'dart:convert';
import 'package:web_socket_channel/web_socket_channel.dart';

void initWebSocket() {
  final channel = WebSocketChannel.connect(
    Uri.parse('ws://你的Laravel地址:6001/app/你的PUSHER_APP_KEY?protocol=7&client=flutter&version=7.4.0'),
  );

  // 订阅公共频道
  channel.sink.add(jsonEncode({
    'event': 'pusher:subscribe',
    'data': {'channel': 'chat'}
  }));

  // 监听事件
  channel.stream.listen((message) {
    final decoded = jsonDecode(message);
    if (decoded['event'] == 'MessageSent') {
      print('收到数据: ${decoded['data']}');
    }
  });
}

三、排查频道认证问题

如果用私有/ Presence频道:

  • 确保routes/channels.php中的认证逻辑正确,比如:
    Broadcast::channel('private-chat.{userId}', function ($user, $userId) {
        return (int)$user->id === (int)$userId;
    });
    
  • Flutter端必须携带有效的用户Token,Laravel端才能通过认证允许订阅。

四、调试技巧

  • Laravel端开启WebSockets调试:在config/websockets.php中设置debug: true,查看storage/logs/laravel.log,确认事件是否被广播、频道订阅是否成功。
  • 用wscat工具直接测试后端:执行wscat -c ws://localhost:6001/app/你的PUSHER_APP_KEY?protocol=7,发送订阅消息后触发MessageSent事件,看是否能收到数据,排除后端问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 13:45:18