Add multi-player and remote bridge support

This commit is contained in:
2026-08-07 02:58:18 +01:00
parent a4f8a807ff
commit 74318eb34e
58 changed files with 3785 additions and 432 deletions
+12 -56
View File
@@ -9,6 +9,7 @@ function createWebBootstrap(options) {
const pool = options && options.pool;
const common = options && options.common;
const configuredPlayerInternalBaseUrl = String(options && options.playerInternalBaseUrl || '').replace(/\/$/, '');
const configuredThinClientBaseUrl = String(options && options.thinClientBaseUrl || process.env.THIN_CLIENT_BASE_URL || '').trim().replace(/\/$/, '');
const uploadDir = String(options && options.uploadDir || '').trim();
const dashboardRefreshIntervalMs = 5000;
const formatDashboardDate = options && options.formatDashboardDate;
@@ -25,49 +26,8 @@ function createWebBootstrap(options) {
const playerSnapshotSockets = new Map();
let dashboardRefreshInFlight = null;
let broadcastDashboardState = null;
let playerInternalBaseUrl = null;
let playerInternalBaseUrlPromise = null;
async function getPlayerInternalBaseUrl() {
if (playerInternalBaseUrl) {
return playerInternalBaseUrl;
}
if (playerInternalBaseUrlPromise) {
return playerInternalBaseUrlPromise;
}
playerInternalBaseUrlPromise = (async function () {
if (!pool) {
return configuredPlayerInternalBaseUrl || null;
}
try {
const [rows] = await pool.query(
`SELECT internal_base_url
FROM d_players
WHERE device_id = '1'
LIMIT 1`
);
const resolvedBaseUrl = String(rows && rows[0] && rows[0].internal_base_url || '').trim().replace(/\/$/, '');
return resolvedBaseUrl || configuredPlayerInternalBaseUrl || null;
} catch (_error) {
return configuredPlayerInternalBaseUrl || null;
}
})().then(function (baseUrl) {
playerInternalBaseUrl = baseUrl || null;
playerInternalBaseUrlPromise = null;
return playerInternalBaseUrl;
}, function () {
playerInternalBaseUrlPromise = null;
return configuredPlayerInternalBaseUrl || null;
});
return playerInternalBaseUrlPromise;
}
async function getPlayerSnapshotSocketUrl(slug) {
const resolvedPlayerInternalBaseUrl = await getPlayerInternalBaseUrl();
function getPlayerSnapshotSocketUrl(slug) {
const resolvedPlayerInternalBaseUrl = configuredThinClientBaseUrl || configuredPlayerInternalBaseUrl;
if (!resolvedPlayerInternalBaseUrl) {
throw new Error('Unable to resolve the player internal base URL.');
}
@@ -78,16 +38,6 @@ function createWebBootstrap(options) {
return url.toString();
}
function storePlayerSnapshot(slug, connections) {
const normalizedSlug = String(slug || '').trim();
const normalizedConnections = Array.isArray(connections) ? connections : [];
playerSnapshotCache.set(normalizedSlug, {
slug: normalizedSlug,
count: normalizedConnections.length,
connections: normalizedConnections
});
}
function clearPlayerSnapshotSocket(slug) {
const key = String(slug || '').trim();
playerSnapshotSockets.delete(key);
@@ -100,12 +50,12 @@ function createWebBootstrap(options) {
}
playerSnapshotSockets.set(key, null);
const socketUrlPromise = getPlayerSnapshotSocketUrl(key);
const authHeaders = createRequestAuthHeaders({
method: 'GET',
pathname: `/ws/screens/${encodeURIComponent(key)}/events`
});
socketUrlPromise.then(function (socketUrl) {
Promise.resolve(getPlayerSnapshotSocketUrl(key)).then(function (socketUrl) {
const socket = new WebSocket(socketUrl, {
headers: authHeaders
});
@@ -117,7 +67,11 @@ function createWebBootstrap(options) {
if (!payload || payload.type !== 'snapshot' || payload.slug !== key) {
return;
}
storePlayerSnapshot(key, payload.connections || []);
playerSnapshotCache.set(key, {
slug: key,
count: Array.isArray(payload.connections) ? payload.connections.length : 0,
connections: Array.isArray(payload.connections) ? payload.connections : []
});
if (broadcastDashboardState) {
broadcastDashboardState().catch(function (error) {
console.error(error);
@@ -151,6 +105,7 @@ function createWebBootstrap(options) {
const dashboardStateService = createDashboardStateService({
pool: pool,
common: common,
thinClientBaseUrl: configuredThinClientBaseUrl,
playerSnapshotCache: playerSnapshotCache,
playerSnapshotSockets: playerSnapshotSockets,
ensurePlayerSnapshotSubscription: ensurePlayerSnapshotSubscription,
@@ -259,6 +214,7 @@ function createWebBootstrap(options) {
return {
upload: upload,
uploadSyncService: uploadSyncService,
playerInternalBaseUrl: configuredPlayerInternalBaseUrl || null,
buildDashboardState: buildDashboardState,
collectUploadReferencesFromSlide: collectUploadReferencesFromSlide,
collectUploadReferencesFromTemplate: collectUploadReferencesFromTemplate,