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

如何在Laravel中监听Whisper事件并将客户端消息存入数据库?

解决Laravel Echo发送消息到服务器并存入数据库的问题

首先明确:whisper 是Laravel Echo用于客户端之间点对点/房间内实时通信的方法,消息会经Redis中转,但Laravel服务器默认不会监听这类whisper消息。要实现消息存入数据库,有两种可行方案:

方案一:监听Redis中的whisper频道

whisper发送的消息会被推送到Redis的特定频道,格式为 presence-{roomName}:client-events(私有房间则为 private-{roomName}:client-events)。你可以创建常驻进程监听该频道,收到消息后写入数据库。

步骤:

  1. 创建Artisan命令监听Redis频道:
<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Facades\Redis;
use App\Models\Message;

class ListenWhisperMessages extends Command
{
    protected $signature = 'redis:listen-whispers {room}';
    protected $description = '监听指定房间的whisper消息并存入数据库';

    public function handle()
    {
        $room = $this->argument('room');
        $channel = "presence-{$room}:client-events"; // 私有房间替换为private-{$room}:client-events

        Redis::subscribe([$channel], function ($message) {
            $payload = json_decode($message, true);
            // 仅处理目标newMsg事件
            if ($payload['event'] === 'client-newMsg') {
                Message::create([
                    'user_id' => $payload['data']['userId'], // 需确保客户端传递用户ID
                    'text' => $payload['data']['text'],
                    'room' => $this->argument('room')
                ]);
            }
        });
    }
}

注意:客户端用whisper('newMsg', ...)时,Redis中的事件名会自动添加client-前缀,因此需监听client-newMsg。

  1. 启动命令:
php artisan redis:listen-whispers room

可借助Supervisor工具保证进程常驻运行。

方案二:改用服务器端事件(更推荐)

既然需求是将消息传给服务器并存库,whisper并非最优选择——它的设计初衷是客户端间通信。更直接的方式如下:

步骤:

  1. 定义服务器端WebSocket事件:
<?php

namespace App\Events;

use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
use App\Models\Message;

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

    public $message;

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

    public function broadcastOn()
    {
        return new PresenceChannel('room'); // 对应目标房间频道
    }
}
  1. 创建API路由接收客户端消息:
// routes/api.php
use App\Models\Message;
use App\Events\NewMessage;
use Illuminate\Http\Request;

Route::post('/send-message', function (Request $request) {
    $message = Message::create([
        'user_id' => auth()->id(),
        'text' => $request->text,
        'room' => $request->room
    ]);

    // 可选:将消息广播给房间内其他客户端
    broadcast(new NewMessage($message))->toOthers();

    return response()->json(['success' => true]);
});
  1. 客户端发送请求并存库:
// 发送消息到服务器API
axios.post('/api/send-message', {
    text: "Hello server. i am from client!",
    room: "room"
}).then(response => {
    console.log('消息已存入数据库');
});

// 可选:监听其他客户端的实时消息
window.Echo.join('room')
    .listen('NewMessage', (e) => {
        console.log('收到新消息:', e.message.text);
    });

内容的提问来源于stack exchange,提问作者H.Rad

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 06:25:20