openvibers/openrestream Commits
OpenRe: the viewer signaling URL is wss://<host>/w/<id> behind the TLS vhost (it gave the loopback worker port). (#15)
Changes
@@@ -234,9 +234,13 @@ function createSessions({ db, config, events, clock, definitions, workers }) {}if (session.protocol === 'webrtc' && ep.publicPort) {// The viewer signaling endpoint, keyed by the session's playback id (never the key), and-- // the mediasoup announced IP clients must be able to reach for media to flow.++ // the mediasoup announced IP clients must be able to reach for media to flow. Behind the TLS++ // vhost (OPENRE_WEBRTC_PUBLIC_PORT=443) it is wss:// with no port, as the WHIP and broadcaster++ // URLs are (store/definitions.js); otherwise ws:// on the worker's own listen port.++ const w = config.webrtc;++ const tls = w.publicPort === 443;descriptor.webrtc = {-- signaling_url: `ws://${config.webrtc.publicHost}:${ep.publicPort}/w/${session.id}`,++ signaling_url: tls ? `wss://${w.publicHost}/w/${session.id}` : `ws://${w.publicHost}:${ep.publicPort}/w/${session.id}`,announced_ip: config.webrtc.media.announcedIp || null,};}@@@ -101,6 +101,18 @@ t('WHIP PATCH sdpfrag: credentials, candidates, end-of-candidates; malformed bod);});++t('behind the TLS vhost (OPENRE_WEBRTC_PUBLIC_PORT=443) the viewer signaling URL is wss:// with no port', async () => {++ const rt = await runtime({ dir: tmpDir(), env: { MEDIASOUP_ANNOUNCED_IP: '203.0.113.7', OPENRE_WEBRTC_PUBLIC_PORT: '443', OPENRE_WEBRTC_PUBLIC_HOST: 'ingest.openre.stream' } });++ const { definition, key } = await rt.store.definitions.create({ owner_subject: OWNER, protocols: ['webrtc'] });++ const w = await rt.store.workers.register({ kind: 'webrtc', endpoints: { publicPort: 9936, egressPort: 19810 } });++ await rt.store.workers.ready(w.id);++ const a = await rt.store.sessions.admit({ definition, key, protocol: 'webrtc', worker: await rt.store.workers.get(w.id) });++ await rt.store.sessions.transition(a.session.id, 'live', { reason: 'media_flowing', actor: 'worker:w' });++ const pb = await rt.store.sessions.playback(await rt.store.sessions.get(a.session.id));++ // The worker listens on loopback 9936; nginx serves it on 443, which is what a browser must use.++ assert.strictEqual(pb.webrtc.signaling_url, `wss://ingest.openre.stream/w/${a.session.id}`);++});++t('a webrtc session playback descriptor is { signaling_url, announced_ip } and carries thumbnail_url', async () => {const rt = await runtime({ dir: tmpDir(), env: { MEDIASOUP_ANNOUNCED_IP: '203.0.113.7' } });const { definition, key } = await rt.store.definitions.create({ owner_subject: OWNER, protocols: ['webrtc'] });
@@ -234,9 +234,13 @@ function createSessions({ db, config, events, clock, definitions, workers }) {
@@ -234,9 +234,13 @@ function createSessions({ db, config, events, clock, definitions, workers }) {
}
}
if (session.protocol === 'webrtc' && ep.publicPort) {
if (session.protocol === 'webrtc' && ep.publicPort) {
// The viewer signaling endpoint, keyed by the session's playback id (never the key), and
// The viewer signaling endpoint, keyed by the session's playback id (never the key), and
- // the mediasoup announced IP clients must be able to reach for media to flow.
+ // the mediasoup announced IP clients must be able to reach for media to flow. Behind the TLS
+ // vhost (OPENRE_WEBRTC_PUBLIC_PORT=443) it is wss:// with no port, as the WHIP and broadcaster
+ // URLs are (store/definitions.js); otherwise ws:// on the worker's own listen port.
+ const w = config.webrtc;
+ const tls = w.publicPort === 443;
descriptor.webrtc = {
descriptor.webrtc = {
- signaling_url: `ws://${config.webrtc.publicHost}:${ep.publicPort}/w/${session.id}`,
+ signaling_url: tls ? `wss://${w.publicHost}/w/${session.id}` : `ws://${w.publicHost}:${ep.publicPort}/w/${session.id}`,
announced_ip: config.webrtc.media.announcedIp || null,
announced_ip: config.webrtc.media.announcedIp || null,
};
};
}
}
@@ -101,6 +101,18 @@ t('WHIP PATCH sdpfrag: credentials, candidates, end-of-candidates; malformed bod
@@ -101,6 +101,18 @@ t('WHIP PATCH sdpfrag: credentials, candidates, end-of-candidates; malformed bod
);
);
});
});
+t('behind the TLS vhost (OPENRE_WEBRTC_PUBLIC_PORT=443) the viewer signaling URL is wss:// with no port', async () => {
+ const rt = await runtime({ dir: tmpDir(), env: { MEDIASOUP_ANNOUNCED_IP: '203.0.113.7', OPENRE_WEBRTC_PUBLIC_PORT: '443', OPENRE_WEBRTC_PUBLIC_HOST: 'ingest.openre.stream' } });
+ const { definition, key } = await rt.store.definitions.create({ owner_subject: OWNER, protocols: ['webrtc'] });
+ const w = await rt.store.workers.register({ kind: 'webrtc', endpoints: { publicPort: 9936, egressPort: 19810 } });
+ await rt.store.workers.ready(w.id);
+ const a = await rt.store.sessions.admit({ definition, key, protocol: 'webrtc', worker: await rt.store.workers.get(w.id) });
+ await rt.store.sessions.transition(a.session.id, 'live', { reason: 'media_flowing', actor: 'worker:w' });
+ const pb = await rt.store.sessions.playback(await rt.store.sessions.get(a.session.id));
+ // The worker listens on loopback 9936; nginx serves it on 443, which is what a browser must use.
+ assert.strictEqual(pb.webrtc.signaling_url, `wss://ingest.openre.stream/w/${a.session.id}`);
+});
+
t('a webrtc session playback descriptor is { signaling_url, announced_ip } and carries thumbnail_url', async () => {
t('a webrtc session playback descriptor is { signaling_url, announced_ip } and carries thumbnail_url', async () => {
const rt = await runtime({ dir: tmpDir(), env: { MEDIASOUP_ANNOUNCED_IP: '203.0.113.7' } });
const rt = await runtime({ dir: tmpDir(), env: { MEDIASOUP_ANNOUNCED_IP: '203.0.113.7' } });
const { definition, key } = await rt.store.definitions.create({ owner_subject: OWNER, protocols: ['webrtc'] });
const { definition, key } = await rt.store.definitions.create({ owner_subject: OWNER, protocols: ['webrtc'] });