HPNP fixes, support multiple stations at once.
This commit is contained in:
parent
2bcdb17910
commit
b444cda03b
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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');
|
||||
|
|
|
@ -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,
|
||||
],
|
||||
]
|
||||
);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue