使用Laravel+Pusher开发实时消息系统遇ws://localhost:6001连接失败
排查Laravel+Pusher实时消息系统WebSocket连接失败问题
问题场景
使用Laravel和Pusher开发实时消息系统时,前端尝试连接ws://localhost:6001失败,报错:Firefox can’t establish a connection to the server at ws://localhost:6001/.
前端代码(Blade模板)
<div> <div id="messages"> @foreach($messages as $message) <div> <strong>{{ $message->user->name }}</strong>: {{ $message->content }} </div> @endforeach </div> <form id="message-form"> <input type="text" id="message-input" placeholder="Type your message..."> <button type="submit">Send</button> </form> </div> @push('script') <script> const messageForm = document.getElementById('message-form'); const messageInput = document.getElementById('message-input'); const messagesDiv = document.getElementById('messages'); // Connect to WebSocket const socket = new WebSocket('ws://localhost:6001'); socket.addEventListener('open', (event) => { console.log('WebSocket connected'); }); socket.addEventListener('message', (event) => { const message = JSON.parse(event.data); messagesDiv.innerHTML += `<div><strong>${message.user.name}</strong>: ${message.content}</div>`; }); messageForm.addEventListener('submit', (event) => { event.preventDefault(); const messageContent = messageInput.value; if (messageContent.trim() !== '') { const message = { content: messageContent, }; socket.send(JSON.stringify(message)); messageInput.value = ''; } }); </script> @endpush @endsection
后端代码(控制器方法)
public function enquiries($id) { $data['information'] = $this->listingService->getById($id); $data['messages'] = Message::with('user')->latest()->get(); return view('listing.frontend.enquiries', $data); } public function store(Request $request) { $request->validate([ 'content' => 'required|string|max:255', ]); $message = new Message(); $message->content = $request->input('content'); $message->user_id = auth()->id(); $message->save(); return redirect()->back(); }
排查步骤
- 确认Laravel Echo Server状态:
ws://localhost:6001是Laravel Echo Server的默认端口,先在终端执行laravel-echo-server start,检查服务是否能正常启动无报错。未安装的话先执行npm install -g laravel-echo-server。 - 检查端口占用:用
lsof -i :6001(Mac/Linux)或netstat -ano | findstr :6001(Windows)查看6001端口是否被其他程序占用,若占用则更换端口或终止占用进程。 - 修正前端连接方式:直接用原生WebSocket连接不符合Pusher使用规范,应改用Laravel Echo配合Pusher.js:
// 先安装依赖:npm install pusher-js laravel-echo import Echo from 'laravel-echo'; import Pusher from 'pusher-js'; window.Pusher = Pusher; window.Echo = new Echo({ broadcaster: 'pusher', key: import.meta.env.VITE_PUSHER_APP_KEY, // 从.env文件获取 cluster: import.meta.env.VITE_PUSHER_APP_CLUSTER, forceTLS: true }); // 监听消息频道 window.Echo.channel('chat') .listen('MessageSent', (e) => { messagesDiv.innerHTML += `<div><strong>${e.message.user.name}</strong>: ${e.message.content}</div>`; }); - 后端添加事件广播:当前
store方法仅保存消息,未触发实时广播,需创建广播事件:// 生成事件:php artisan make:event MessageSent namespace App\Events; use App\Models\Message; use Illuminate\Broadcasting\Channel; use Illuminate\Broadcasting\InteractsWithSockets; use Illuminate\Broadcasting\ShouldBroadcast; use Illuminate\Foundation\Events\Dispatchable; use Illuminate\Queue\SerializesModels; class MessageSent implements ShouldBroadcast { use Dispatchable, InteractsWithSockets, SerializesModels; public $message; public function __construct(Message $message) { $this->message = $message->load('user'); } public function broadcastOn() { return new Channel('chat'); } } // 在store方法中添加广播逻辑 public function store(Request $request) { // ... 原有保存代码 broadcast(new \App\Events\MessageSent($message))->toOthers(); return redirect()->back(); } - 核对.env配置:确保广播驱动和Pusher参数正确:
BROADCAST_DRIVER=pusher PUSHER_APP_ID=你的Pusher应用ID PUSHER_APP_KEY=你的Pusher应用Key PUSHER_APP_SECRET=你的Pusher应用Secret PUSHER_APP_CLUSTER=你的Pusher集群(比如mt1) - 检查CORS配置:在
config/cors.php中设置:return [ 'paths' => ['api/*', 'broadcasting/auth'], 'allowed_methods' => ['*'], 'allowed_origins' => ['*'], // 生产环境替换为具体前端域名 'allowed_origins_patterns' => [], 'allowed_headers' => ['*'], 'exposed_headers' => [], 'max_age' => 0, 'supports_credentials' => true, ];
内容的提问来源于stack exchange,提问作者abu abu
相关产品推荐
相关产品推荐

