feat: 添加实时广播功能,支持风险预警、玩法切换和赔率更新,增强大厅公共频道的广播能力

This commit is contained in:
2026-05-13 14:36:28 +08:00
parent d8e9fa5f4c
commit 6defe6bb0d
7 changed files with 436 additions and 1 deletions

View File

@@ -2,12 +2,18 @@
namespace App\Services\Draw;
use App\Events\OddsUpdateBroadcast;
use App\Events\PlayToggleBroadcast;
use App\Events\RiskSoldOutBroadcast;
use App\Events\RiskWarningBroadcast;
use App\Events\DrawCountdownBroadcast;
use App\Events\DrawStatusChangeBroadcast;
use App\Events\DrawResultPublishedBroadcast;
/**
* 对齐界面文档 §2.1`draw.countdown``draw.status_change``result.published`(频道 `lottery-hall`)。
* 对齐界面文档 §2.1大厅公共频道广播(`lottery-hall`)。
* 包含draw.countdown、draw.status_change、result.published、
* risk.sold_out、risk.warning、play.toggle、odds.update
*/
final class LotteryHallRealtimeBroadcaster
{
@@ -66,6 +72,67 @@ final class LotteryHallRealtimeBroadcaster
broadcast(new DrawResultPublishedBroadcast($data, (int) floor(microtime(true) * 1000)));
}
/** `risk.sold_out` —— 号码赔付池耗尽 */
public function notifyRiskSoldOut(int $drawId, string $drawNo, string $normalizedNumber): void
{
if (! $this->driverSupportsRealtime()) {
return;
}
broadcast(new RiskSoldOutBroadcast(
$drawId,
$drawNo,
$normalizedNumber,
(int) floor(microtime(true) * 1000),
));
}
/** `risk.warning` —— 号码赔付池占用超 80% 预警 */
public function notifyRiskWarning(int $drawId, string $drawNo, string $normalizedNumber, float $usageRatio): void
{
if (! $this->driverSupportsRealtime()) {
return;
}
broadcast(new RiskWarningBroadcast(
$drawId,
$drawNo,
$normalizedNumber,
$usageRatio,
(int) floor(microtime(true) * 1000),
));
}
/** `play.toggle` —— 玩法开关变更 */
public function notifyPlayToggle(string $playCode, bool $enabled, ?string $reason = null): void
{
if (! $this->driverSupportsRealtime()) {
return;
}
broadcast(new PlayToggleBroadcast(
$playCode,
$enabled,
$reason,
(int) floor(microtime(true) * 1000),
));
}
/** `odds.update` —— 赔率变更 */
public function notifyOddsUpdate(int $versionId, string $versionName, ?array $diff = null): void
{
if (! $this->driverSupportsRealtime()) {
return;
}
broadcast(new OddsUpdateBroadcast(
$versionId,
$versionName,
$diff,
(int) floor(microtime(true) * 1000),
));
}
private function driverSupportsRealtime(): bool
{
$default = config('broadcasting.default');

View File

@@ -0,0 +1,48 @@
<?php
namespace App\Services;
use App\Events\BalanceUpdateBroadcast;
/**
* 玩家私有频道实时广播。
*
* 对齐界面文档 §2.1balance.update频道 `player.{id}`)。
* 注意:玩家私有频道广播与大厅公共频道分开管理。
*/
final class PlayerRealtimeBroadcaster
{
/** `balance.update` —— 钱包余额变动 */
public function notifyBalanceUpdate(
int $playerId,
string $currencyCode,
int $balanceMinor,
int $changeMinor,
string $reason,
): void {
if (! $this->driverSupportsRealtime()) {
return;
}
broadcast(new BalanceUpdateBroadcast(
$playerId,
$currencyCode,
$balanceMinor,
$changeMinor,
$reason,
(int) floor(microtime(true) * 1000),
));
}
private function driverSupportsRealtime(): bool
{
$default = config('broadcasting.default');
if ($default === null || $default === 'null') {
return false;
}
$driver = config("broadcasting.connections.{$default}.driver") ?? $default;
return ! in_array($driver, ['null', 'log'], true);
}
}