main: 优化消息处理逻辑与 Redis 发布
- 调整消息解析流程,支持 JSON 解码与模型实例化 - 增加 `appendMessage` 方法的保存控制参数 - 修复因保存控制导致的重复发布问题 - 优化 Redis 发布逻辑,支持消息内容推送 - 更新注释与待优化标记,提升代码可读性
This commit is contained in:
@@ -3,6 +3,7 @@
|
|||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
use App\Http\Resources\MessageResource;
|
use App\Http\Resources\MessageResource;
|
||||||
|
use App\Models\Message;
|
||||||
use App\Services\ChatService;
|
use App\Services\ChatService;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Http\Response;
|
use Illuminate\Http\Response;
|
||||||
@@ -72,7 +73,8 @@ class ChatSessionSseController extends Controller
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$msg = $this->service->getMessage($sessionId, $payload);
|
$msg = json_decode($payload, true, 512, JSON_THROW_ON_ERROR);
|
||||||
|
$msg = new Message($msg);
|
||||||
if ($msg && $msg->seq > $lastSentSeq) {
|
if ($msg && $msg->seq > $lastSentSeq) {
|
||||||
if ($msg->seq > $lastSentSeq + 1) {
|
if ($msg->seq > $lastSentSeq + 1) {
|
||||||
$this->sendBacklog($sessionId, $lastSentSeq, $limit);
|
$this->sendBacklog($sessionId, $lastSentSeq, $limit);
|
||||||
|
|||||||
@@ -59,13 +59,13 @@ class ChatService
|
|||||||
* @param bool|null $wasDeduped 是否发生了去重(可选,按引用返回)
|
* @param bool|null $wasDeduped 是否发生了去重(可选,按引用返回)
|
||||||
* @return Message 返回成功追加的消息实例。如果存在去重键并已存在重复消息,则返回现有的消息。
|
* @return Message 返回成功追加的消息实例。如果存在去重键并已存在重复消息,则返回现有的消息。
|
||||||
*/
|
*/
|
||||||
public function appendMessage(array $dto, ?bool &$wasDeduped = null): Message
|
public function appendMessage(array $dto, ?bool &$wasDeduped = null, bool $save = true): Message
|
||||||
{
|
{
|
||||||
$messageRef = null;
|
$messageRef = null;
|
||||||
$isNew = false;
|
$isNew = false;
|
||||||
$wasDeduped = false;
|
$wasDeduped = false;
|
||||||
|
|
||||||
DB::transaction(function () use ($dto, &$messageRef, &$isNew, &$wasDeduped) {
|
DB::transaction(function () use ($dto, &$messageRef, &$isNew, &$wasDeduped, $save) {
|
||||||
/** @var ChatSession $session */
|
/** @var ChatSession $session */
|
||||||
$session = ChatSession::query()
|
$session = ChatSession::query()
|
||||||
->whereKey($dto['session_id'])
|
->whereKey($dto['session_id'])
|
||||||
@@ -104,7 +104,9 @@ class ChatService
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$message->save();
|
if ($save) {
|
||||||
|
$message->save();
|
||||||
|
}
|
||||||
$isNew = true;
|
$isNew = true;
|
||||||
} catch (QueryException $e) {
|
} catch (QueryException $e) {
|
||||||
if ($this->isUniqueConstraint($e) && $dedupeKey) {
|
if ($this->isUniqueConstraint($e) && $dedupeKey) {
|
||||||
@@ -131,8 +133,10 @@ class ChatService
|
|||||||
|
|
||||||
$messageRef = $message;
|
$messageRef = $message;
|
||||||
|
|
||||||
if ($isNew) {
|
if ($isNew && $save) {
|
||||||
DB::afterCommit(fn () => $this->publishMessageAppended($message));
|
DB::afterCommit(fn () => $this->publishMessageAppended($message));
|
||||||
|
} else {
|
||||||
|
$this->publishMessageAppended($message);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -290,7 +294,8 @@ class ChatService
|
|||||||
|
|
||||||
$channel = "session:{$message->session_id}:messages";
|
$channel = "session:{$message->session_id}:messages";
|
||||||
try {
|
try {
|
||||||
Redis::publish($channel, $message->message_id);
|
//todo::优化这里。
|
||||||
|
Redis::publish($channel, json_encode($message->toArray(), JSON_UNESCAPED_UNICODE|JSON_INVALID_UTF8_IGNORE));
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
logger()->warning('Redis publish failed', [
|
logger()->warning('Redis publish failed', [
|
||||||
'session_id' => $message->session_id,
|
'session_id' => $message->session_id,
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ class OutputSink
|
|||||||
'delta_index' => $deltaIndex,
|
'delta_index' => $deltaIndex,
|
||||||
]),
|
]),
|
||||||
'dedupe_key' => $dedupeKey,
|
'dedupe_key' => $dedupeKey,
|
||||||
]);
|
],$wasDupe,false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user