1.优化中奖后只推送一帧中奖记录消息

This commit is contained in:
2026-05-25 16:46:47 +08:00
parent 21caa6d548
commit c10908b4da
4 changed files with 111 additions and 5 deletions

View File

@@ -9,6 +9,7 @@ use app\common\model\UserWalletRecord;
use app\common\service\GameHotDataCoordinator;
use app\common\service\GameHotDataLock;
use support\Log;
use support\Redis;
use support\think\Db;
use Throwable;
@@ -23,6 +24,10 @@ final class GameLiveService
private const EVT_PERIOD_LOCKED = 'period.locked';
private const EVT_PERIOD_OPENED = 'period.opened';
private const EVT_PERIOD_PAYOUT = 'period.payout';
/** period.tick 边界帧去重finished / void 每期只推一次TTL 兼顾跨进程与跨期重启 */
private const TICK_BOUNDARY_DEDUP_KEY_PREFIX = 'dfw:v1:ws:tick:boundary:';
private const TICK_BOUNDARY_DEDUP_TTL_SECONDS = 300;
private const KEY_PERIOD_SECONDS = 'period_seconds';
private const KEY_BET_SECONDS = 'bet_seconds';
private const KEY_PAYOUT_SECONDS = 'payout_seconds';
@@ -923,9 +928,53 @@ final class GameLiveService
'server_time' => time(),
];
if (!self::shouldPublishPeriodTick($status, $periodNo)) {
return;
}
GameWebSocketEventBus::publish(self::EVT_PERIOD_TICK, $payload);
}
/**
* period.tick 状态过滤与《36字花-移动端接口设计草案》7.1.3 推送规则对齐):
* - betting / locked保持每秒推送
* - payouting完全静默中奖信息已通过 period.opened / period.payout / jackpot.hit / wallet.changed 通知)
* - finished / void每个期号只推一次边界帧告知前端本期收尾随后静默直到下一期 betting
*/
private static function shouldPublishPeriodTick(string $status, string $periodNo): bool
{
if ($status === 'payouting') {
return false;
}
if ($status === 'finished' || $status === 'void') {
if ($periodNo === '') {
return true;
}
return self::markBoundaryFrameOnce($periodNo, $status);
}
return true;
}
/**
* 边界帧去重SET NX EX占位成功首次返回 true已存在返回 false。Redis 异常时降级为放行。
*/
private static function markBoundaryFrameOnce(string $periodNo, string $status): bool
{
$key = self::TICK_BOUNDARY_DEDUP_KEY_PREFIX . $periodNo . ':' . $status;
try {
$client = Redis::connection()->client();
if (!is_object($client) || !method_exists($client, 'set')) {
return true;
}
$ok = $client->set($key, '1', ['nx', 'ex' => self::TICK_BOUNDARY_DEDUP_TTL_SECONDS]);
return $ok === true;
} catch (Throwable) {
return true;
}
}
/**
* @param array<string, mixed> $record game_record 行
*/