如何正确集成Laravel Reverb与React Native Expo实现实时通信?
Laravel Reverb + React Native Expo Socket.io 集成指南(解决连接失败问题)
一、后端Laravel Reverb 配置确认
1. 基础环境与.env配置
确保已安装laravel/reverb,并在.env中配置正确参数:
BROADCAST_DRIVER=reverb REVERB_APP_ID=你的APP_ID REVERB_APP_KEY=你的APP_KEY REVERB_APP_SECRET=你的APP_SECRET REVERB_HOST=0.0.0.0 # 本地测试用0.0.0.0,生产用服务器域名/IP REVERB_PORT=8080 REVERB_SCHEME=http # 生产环境改为https
2. CORS 配置
修改config/cors.php,允许Reverb相关路由跨域并支持凭证:
return [ 'paths' => ['api/*', 'broadcasting/auth', 'reverb/*'], 'allowed_methods' => ['*'], 'allowed_origins' => ['*'], // 生产环境限制为你的RN应用域名/IP 'allowed_origins_patterns' => [], 'allowed_headers' => ['*'], 'exposed_headers' => [], 'max_age' => 0, 'supports_credentials' => true, ];
3. 频道定义
在routes/channels.php中配置业务所需的私人/ Presence频道:
// 用户资料更新私人频道 Broadcast::channel('user.{userId}', function ($user, $userId) { return (int)$user->id === (int)$userId; }); // 聊天房间频道 Broadcast::channel('chat.{roomId}', function ($user, $roomId) { // 这里可添加用户聊天室权限验证逻辑 return true; });
4. 启动Reverb服务
执行命令启动Reverb,不要依赖php artisan serve的内置服务器:
php artisan reverb:start
二、前端React Native Expo 集成
1. 依赖安装(版本兼容)
Reverb仅兼容Socket.io v4.x,确保安装对应版本:
npm install socket.io-client@4.x # 或 yarn add socket.io-client@4.x
2. 创建Socket连接实例
注意:本地测试时不能用localhost,需用电脑局域网IP(如192.168.1.100),否则模拟器/真机无法访问服务器。
import { io } from 'socket.io-client'; // 从环境变量读取配置,建议用Expo的环境变量管理 const REVERB_URL = process.env.EXPO_PUBLIC_REVERB_URL; const REVERB_APP_KEY = process.env.EXPO_PUBLIC_REVERB_APP_KEY; const socket = io(REVERB_URL, { transports: ['websocket'], // 强制使用WebSocket,避免轮询问题 auth: { token: '用户的API Bearer Token', // 用于Laravel频道权限验证 }, query: { app_key: REVERB_APP_KEY, }, }); // 监听连接状态 socket.on('connect', () => console.log('Socket连接成功')); socket.on('connect_error', (err) => console.error('连接失败:', err)); socket.on('disconnect', () => console.log('Socket断开连接')); export default socket;
3. 订阅频道与监听事件
用户资料实时更新示例
import socket from './socket'; import { useState } from 'react'; const UserProfile = ({ userId }) => { const [user, setUser] = useState({}); // 订阅用户私人频道 socket.emit('subscribe', { channel: `user.${userId}`, }); // 监听资料更新事件 socket.on(`user.${userId}.user-updated`, (updatedData) => { setUser(prev => ({ ...prev, ...updatedData })); }); return ( // 渲染用户资料UI ); };
聊天功能示例
import socket from './socket'; import { useState } from 'react'; const ChatRoom = ({ roomId, currentUserId }) => { const [messages, setMessages] = useState([]); const [inputText, setInputText] = useState(''); // 订阅聊天室频道 socket.emit('subscribe', { channel: `chat.${roomId}`, }); // 发送消息 const sendMessage = () => { socket.emit('client-event', { channel: `chat.${roomId}`, event: 'message-sent', data: { user_id: currentUserId, content: inputText, timestamp: Date.now(), }, }); setInputText(''); }; // 监听新消息 socket.on(`chat.${roomId}.message-sent`, (newMsg) => { setMessages(prev => [...prev, newMsg]); }); return ( // 渲染聊天UI ); };
三、常见连接失败排查点
- 局域网访问问题:本地测试时,确保RN设备与Laravel服务器在同一局域网,服务器防火墙开放8080端口
- 版本不兼容:必须使用Socket.io v4.x,v5.x及以上与Reverb不兼容
- 认证失败:私人/Presence频道需传递有效的用户Token,Laravel会通过
broadcasting/auth路由验证权限 - Reverb服务未启动:确认
php artisan reverb:start已执行,且终端未关闭
四、后端触发实时事件示例
以用户资料更新为例,创建广播事件并触发:
// 生成UserUpdated事件 php artisan make:event UserUpdated // 编辑事件类 class UserUpdated implements ShouldBroadcast { use Dispatchable, InteractsWithSockets, SerializesModels; public $user; public function __construct(User $user) { $this->user = $user; } public function broadcastOn() { return new PrivateChannel('user.' . $this->user->id); } public function broadcastAs() { return 'user-updated'; } public function broadcastWith() { return [ 'id' => $this->user->id, 'name' => $this->user->name, 'avatar' => $this->user->avatar, ]; } } // 在User模型中触发事件 protected static function booted() { static::updated(function ($user) { broadcast(new UserUpdated($user))->toOthers(); }); }
内容的提问来源于stack exchange,提问作者Gina UK
相关产品推荐
相关产品推荐

