Files
lotteryLaravel/app/Services/Draw/LotteryHallRealtimeBroadcaster.php

81 lines
2.4 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
namespace App\Services\Draw;
use App\Events\DrawCountdownBroadcast;
use App\Events\DrawResultPublishedBroadcast;
use App\Events\DrawStatusChangeBroadcast;
/**
* 对齐界面文档 §2.1`draw.countdown`、`draw.status_change`、`result.published`(频道 `lottery-hall`)。
*/
final class LotteryHallRealtimeBroadcaster
{
public function __construct(
private readonly DrawHallSnapshotBuilder $snapshot,
) {}
/** 每秒调度:`draw.countdown` */
public function countdownPulse(): void
{
if (! $this->driverSupportsRealtime()) {
return;
}
$data = $this->snapshot->build();
$ms = (int) floor(microtime(true) * 1000);
broadcast(new DrawCountdownBroadcast($data, $ms));
}
/**
* Tick 首尾对比:**数据库**当期指纹({@see DrawHallSnapshotBuilder::hallTargetFingerprint})变了再发,
* 载荷仍为 {@see DrawHallSnapshotBuilder::build()}(含未到 tick 时对 `open` 的展示规范化)。
*/
public function notifyStatusChangeIfHallDbChanged(?array $fpBefore, ?array $fpAfter, ?array $snapshotPayload): void
{
if (! $this->driverSupportsRealtime()) {
return;
}
if (($fpBefore['draw_no'] ?? null) === ($fpAfter['draw_no'] ?? null)
&& ($fpBefore['status'] ?? null) === ($fpAfter['status'] ?? null)) {
return;
}
$this->notifyStatusChange($snapshotPayload);
}
/** `draw.status_change`(管理端发布后等不与 tick 同路径时使用)。 */
public function notifyStatusChange(?array $data): void
{
if (! $this->driverSupportsRealtime()) {
return;
}
broadcast(new DrawStatusChangeBroadcast($data, (int) floor(microtime(true) * 1000)));
}
/** `result.published` */
public function notifyResultPublished(?array $data): void
{
if (! $this->driverSupportsRealtime()) {
return;
}
broadcast(new DrawResultPublishedBroadcast($data, (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);
}
}