1.重构实时消息WebSocket连接
2.MySQL备份
This commit is contained in:
93
app/common/service/GameWebSocketEventBus.php
Normal file
93
app/common/service/GameWebSocketEventBus.php
Normal file
@@ -0,0 +1,93 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\common\service;
|
||||
|
||||
use support\Redis;
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* 通过 Redis 列表在不同进程间投递 WebSocket 事件。
|
||||
*/
|
||||
final class GameWebSocketEventBus
|
||||
{
|
||||
private const KEY_QUEUE = 'dfw:v1:ws:event:queue';
|
||||
private const MAX_BATCH = 100;
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $data
|
||||
*/
|
||||
public static function publish(string $topic, array $data): void
|
||||
{
|
||||
$topic = trim($topic);
|
||||
if ($topic === '') {
|
||||
return;
|
||||
}
|
||||
$payload = [
|
||||
'topic' => $topic,
|
||||
'event' => $topic,
|
||||
'data' => $data,
|
||||
'server_time' => time(),
|
||||
];
|
||||
$json = json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
|
||||
if (!is_string($json) || $json === '') {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
Redis::lPush(self::KEY_QUEUE, $json);
|
||||
} catch (Throwable) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return list<array{topic:string,event:string,data:array<string,mixed>,server_time:int}>
|
||||
*/
|
||||
public static function popBatch(int $limit = self::MAX_BATCH): array
|
||||
{
|
||||
if ($limit <= 0) {
|
||||
return [];
|
||||
}
|
||||
if ($limit > self::MAX_BATCH) {
|
||||
$limit = self::MAX_BATCH;
|
||||
}
|
||||
|
||||
$out = [];
|
||||
try {
|
||||
for ($i = 0; $i < $limit; $i++) {
|
||||
$raw = Redis::rPop(self::KEY_QUEUE);
|
||||
if (!is_string($raw) || $raw === '') {
|
||||
break;
|
||||
}
|
||||
$decoded = json_decode($raw, true);
|
||||
if (!is_array($decoded)) {
|
||||
continue;
|
||||
}
|
||||
$topicRaw = $decoded['topic'] ?? '';
|
||||
$eventRaw = $decoded['event'] ?? '';
|
||||
$dataRaw = $decoded['data'] ?? [];
|
||||
$serverTimeRaw = $decoded['server_time'] ?? time();
|
||||
if (!is_string($topicRaw) || trim($topicRaw) === '') {
|
||||
continue;
|
||||
}
|
||||
$topic = trim($topicRaw);
|
||||
$event = is_string($eventRaw) && trim($eventRaw) !== '' ? trim($eventRaw) : $topic;
|
||||
$data = is_array($dataRaw) ? $dataRaw : [];
|
||||
$serverTime = filter_var($serverTimeRaw, FILTER_VALIDATE_INT);
|
||||
if ($serverTime === false || $serverTime <= 0) {
|
||||
$serverTime = time();
|
||||
}
|
||||
$out[] = [
|
||||
'topic' => $topic,
|
||||
'event' => $event,
|
||||
'data' => $data,
|
||||
'server_time' => $serverTime,
|
||||
];
|
||||
}
|
||||
} catch (Throwable) {
|
||||
return $out;
|
||||
}
|
||||
|
||||
return $out;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user