HPNP fixes, support multiple stations at once.

This commit is contained in:
Buster Neece 2023-12-07 08:44:29 -06:00
parent 2bcdb17910
commit b444cda03b
No known key found for this signature in database
6 changed files with 50 additions and 31 deletions

View File

@ -23,13 +23,19 @@ export const nowPlayingProps = {
},
};
interface NowPlayingSSETime {
interface SSETimePayload {
timestamp: number
}
interface NowPlayingSSEResponse {
interface SSENowPlayingPayload {
station: string,
np: ApiNowPlaying,
triggers: string[] | null
}
interface SSEResponse {
type: string,
payload: NowPlayingSSETime | ApiNowPlaying
payload: SSETimePayload | SSENowPlayingPayload
}
export default function useNowPlaying(props) {
@ -67,16 +73,16 @@ export default function useNowPlaying(props) {
const {data} = useEventSource(sseUri.value);
watch(data, (dataRaw: string) => {
const jsonData: NowPlayingSSEResponse = JSON.parse(dataRaw);
const jsonData: SSEResponse = JSON.parse(dataRaw);
if (jsonData.type === 'time') {
currentTime.value = jsonData.payload.timestamp;
} else if (jsonData.type === 'nowplaying') {
if (npUpdated.value === 0) {
setNowPlaying(jsonData.payload);
setNowPlaying(jsonData.payload.np);
} else {
setTimeout(() => {
setNowPlaying(jsonData.payload);
setNowPlaying(jsonData.payload.np);
}, 3000);
}
}

View File

@ -9,8 +9,9 @@ const publicPort: number = 6050;
const internalPort: number = 6055;
interface NowPlayingSubmission {
channel: string,
payload: ApiNowPlaying
station: string,
np: ApiNowPlaying,
triggers: string[] | null
}
interface StationChannelState extends Record<string, unknown> {
@ -60,24 +61,34 @@ setInterval(() => {
const publicServer = new App();
publicServer.get('/:station', async (req, res) => {
const stationId: string = req.params.station;
res.set("Access-Control-Allow-Origin", "*");
res.set("X-Accel-Buffering", "no");
if (!stationChannels.has(stationId)) {
res.status(404).send('Station Not Found');
const stations: string[] = req.params.station.split(',');
let anyStationsFound: boolean = false;
for (const stationId of stations) {
if (stationChannels.has(stationId)) {
anyStationsFound = true;
break;
}
}
if (!anyStationsFound) {
return res.status(404).send('Station(s) Not Found');
}
const session = await createSession(req, res, {
retry: 5000,
headers: {
"Access-Control-Allow-Origin": "*",
"X-Accel-Buffering": "no",
}
keepAlive: null,
});
timeChannel.register(session);
const stationChannel = stationChannels.get(stationId);
stationChannel.register(session);
for (const stationId of stations) {
const stationChannel = stationChannels.get(stationId);
stationChannel.register(session);
}
});
publicServer.listen(publicPort, () => {
@ -92,12 +103,12 @@ privateServer.post('/', async (req, res) => {
const body: NowPlayingSubmission = req.body;
console.debug(
`NP Update received for channel ${body.channel}.`
`NP Update received for channel ${body.station}.`
);
let channel: Channel<StationChannelState>;
if (stationChannels.has(body.channel)) {
channel = stationChannels.get(body.channel);
if (stationChannels.has(body.station)) {
channel = stationChannels.get(body.station);
} else {
// Create a new channel if none exists.
channel = createChannel();
@ -107,14 +118,14 @@ privateServer.post('/', async (req, res) => {
payload: channel.state.lastMessage
});
});
stationChannels.set(body.channel, channel);
stationChannels.set(body.station, channel);
}
channel.state.timestamp = unixTimestamp();
channel.state.lastMessage = body.payload;
channel.state.lastMessage = body;
channel.broadcast({
type: 'nowplaying',
payload: body.payload
payload: body
});
return res.send('OK');

View File

@ -25,14 +25,15 @@ final class HpNp
return $this->environment->isDocker() && !$this->environment->isTesting();
}
public function publishToStation(Station $station, mixed $message): void
public function publishToStation(Station $station, mixed $message, array $triggers = []): void
{
$this->client->post(
'http://localhost:6055',
[
'json' => [
'channel' => $station->getShortName(),
'payload' => $message,
'station' => $station->getShortName(),
'np' => $message,
'triggers' => $triggers,
],
]
);

View File

@ -60,7 +60,7 @@ final class Dispatcher
// Always dispatch the special "local" updater task.
try {
$this->localHandler->dispatch($station, $np);
$this->localHandler->dispatch($station, $np, $triggers);
} catch (Throwable $e) {
$this->logger->error(
sprintf('%s L%d: %s', $e->getFile(), $e->getLine(), $e->getMessage()),
@ -161,7 +161,7 @@ final class Dispatcher
$np->resolveUrls($this->router->getBaseUrl());
$np->cache = 'event';
$this->localHandler->dispatch($station, $np);
$this->localHandler->dispatch($station, $np, []);
$webhookType = $webhook->getType();
$webhookClass = $webhookType->getClass();

View File

@ -27,7 +27,8 @@ final class LocalWebhookHandler
public function dispatch(
Station $station,
NowPlaying $np
NowPlaying $np,
array $triggers
): void {
$fsUtils = new Filesystem();
@ -69,7 +70,7 @@ final class LocalWebhookHandler
// Publish to websocket library
if ($this->hpNp->isSupported()) {
$this->hpNp->publishToStation($station, $np);
$this->hpNp->publishToStation($station, $np, $triggers);
}
}
}

View File

@ -96,7 +96,7 @@ server {
}
# SSE Now Playing Updates
location ~ ^/api/live/nowplaying/(\w+)$ {
location ~ ^/api/live/nowplaying/(.*)$ {
include proxy_params;
proxy_pass http://hpnp/$1?$args;
}