2020-05-21 12:20:46 +08:00
|
|
|
let STUN_TURN_DICT;
|
|
|
|
let MAPPED_STUN_TURN_DICT;
|
2022-12-17 06:14:28 +08:00
|
|
|
let TURN_CACHE_VALID_UNTIL = Math.floor(Date.now() / 1000);
|
2022-12-19 06:09:30 +08:00
|
|
|
let HAS_SEEN_TURN_SERVER = false;
|
2018-07-10 05:29:27 +08:00
|
|
|
|
|
|
|
const fetchStunTurnServers = function (sessionToken) {
|
2022-12-17 06:14:28 +08:00
|
|
|
const now = Math.floor(Date.now() / 1000);
|
2024-05-29 21:26:11 +08:00
|
|
|
const MEDIA = window.meetingClientSettings.public.media;
|
|
|
|
const CACHE_STUN_TURN = MEDIA.cacheStunTurnServers;
|
|
|
|
|
2022-12-17 06:14:28 +08:00
|
|
|
if (STUN_TURN_DICT && CACHE_STUN_TURN && now < TURN_CACHE_VALID_UNTIL) return Promise.resolve(STUN_TURN_DICT);
|
2020-05-21 12:20:46 +08:00
|
|
|
|
2018-07-10 05:29:27 +08:00
|
|
|
const handleStunTurnResponse = ({ stunServers, turnServers }) => {
|
|
|
|
if (!stunServers && !turnServers) {
|
2020-05-21 12:20:46 +08:00
|
|
|
return Promise.reject(new Error('Could not fetch STUN/TURN servers'));
|
2018-07-10 05:29:27 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
const turnReply = [];
|
2022-12-17 06:14:28 +08:00
|
|
|
let max_ttl = null;
|
2023-02-18 01:39:52 +08:00
|
|
|
turnServers.forEach((turnEntry) => {
|
2018-07-10 05:29:27 +08:00
|
|
|
const { password, url, username } = turnEntry;
|
2022-12-17 06:14:28 +08:00
|
|
|
const valid_until = parseInt(username.split(':')[0]);
|
|
|
|
if (!max_ttl) {
|
|
|
|
max_ttl = valid_until;
|
|
|
|
} else if (valid_until < max_ttl) {
|
|
|
|
max_ttl = valid_until;
|
|
|
|
}
|
2018-07-10 05:29:27 +08:00
|
|
|
turnReply.push({
|
|
|
|
urls: url,
|
|
|
|
password,
|
|
|
|
username,
|
|
|
|
});
|
2022-12-19 06:09:30 +08:00
|
|
|
HAS_SEEN_TURN_SERVER = true;
|
2018-07-10 05:29:27 +08:00
|
|
|
});
|
2022-12-17 06:14:28 +08:00
|
|
|
TURN_CACHE_VALID_UNTIL = max_ttl;
|
2018-07-10 05:29:27 +08:00
|
|
|
|
2020-05-21 12:20:46 +08:00
|
|
|
const stDictionary = {
|
2018-07-10 05:29:27 +08:00
|
|
|
stun: stunServers.map(server => server.url),
|
|
|
|
turn: turnReply,
|
|
|
|
};
|
2020-05-21 12:20:46 +08:00
|
|
|
|
|
|
|
STUN_TURN_DICT = stDictionary;
|
|
|
|
|
|
|
|
return Promise.resolve(stDictionary);
|
2018-07-10 05:29:27 +08:00
|
|
|
};
|
|
|
|
|
2024-05-29 21:26:11 +08:00
|
|
|
const STUN_TURN_FETCH_URL = window.meetingClientSettings.public.media.stunTurnServersFetchAddress;
|
|
|
|
|
2018-07-10 05:29:27 +08:00
|
|
|
const url = `${STUN_TURN_FETCH_URL}?sessionToken=${sessionToken}`;
|
2021-11-19 05:52:20 +08:00
|
|
|
return fetch(url, { credentials: 'include' })
|
2018-07-10 05:29:27 +08:00
|
|
|
.then(res => res.json())
|
2020-05-26 01:32:24 +08:00
|
|
|
.then(handleStunTurnResponse);
|
2020-02-27 03:48:40 +08:00
|
|
|
};
|
2018-07-10 05:29:27 +08:00
|
|
|
|
2020-05-21 12:20:46 +08:00
|
|
|
const mapStunTurn = ({ stun, turn }) => {
|
|
|
|
const rtcStuns = stun.map(url => ({ urls: url }));
|
|
|
|
const rtcTurns = turn.map(t => ({ urls: t.urls, credential: t.password, username: t.username }));
|
|
|
|
return rtcStuns.concat(rtcTurns);
|
2020-02-27 03:48:40 +08:00
|
|
|
};
|
2018-07-10 05:29:27 +08:00
|
|
|
|
2020-05-21 12:20:46 +08:00
|
|
|
const getFallbackStun = () => {
|
2024-05-29 21:26:11 +08:00
|
|
|
const FALLBACK_STUN_SERVER = window.meetingClientSettings.public.media.fallbackStunServer;
|
|
|
|
|
2020-05-26 01:32:24 +08:00
|
|
|
const stun = FALLBACK_STUN_SERVER ? [FALLBACK_STUN_SERVER] : [];
|
2020-05-21 12:20:46 +08:00
|
|
|
return { stun, turn: [] };
|
2020-05-26 01:32:24 +08:00
|
|
|
};
|
2020-05-21 12:20:46 +08:00
|
|
|
|
2024-05-29 21:26:11 +08:00
|
|
|
const getMappedFallbackStun = () => {
|
|
|
|
const FALLBACK_STUN_SERVER = window.meetingClientSettings.public.media.fallbackStunServer;
|
|
|
|
|
|
|
|
return (FALLBACK_STUN_SERVER ? [{ urls: FALLBACK_STUN_SERVER }] : []);
|
|
|
|
};
|
2020-05-21 12:20:46 +08:00
|
|
|
|
2018-07-10 05:29:27 +08:00
|
|
|
const fetchWebRTCMappedStunTurnServers = function (sessionToken) {
|
2024-05-29 21:26:11 +08:00
|
|
|
const MEDIA = window.meetingClientSettings.public.media;
|
|
|
|
const CACHE_STUN_TURN = MEDIA.cacheStunTurnServers;
|
|
|
|
|
2018-07-10 05:29:27 +08:00
|
|
|
return new Promise(async (resolve, reject) => {
|
|
|
|
try {
|
2022-12-17 06:14:28 +08:00
|
|
|
const now = Math.floor(Date.now() / 1000);
|
|
|
|
if (MAPPED_STUN_TURN_DICT && CACHE_STUN_TURN && now < TURN_CACHE_VALID_UNTIL) {
|
2020-05-21 12:20:46 +08:00
|
|
|
return resolve(MAPPED_STUN_TURN_DICT);
|
|
|
|
}
|
|
|
|
|
2020-05-26 01:32:24 +08:00
|
|
|
const stDictionary = await fetchStunTurnServers(sessionToken);
|
2020-05-21 12:20:46 +08:00
|
|
|
|
|
|
|
MAPPED_STUN_TURN_DICT = mapStunTurn(stDictionary);
|
|
|
|
return resolve(MAPPED_STUN_TURN_DICT);
|
2018-07-10 05:29:27 +08:00
|
|
|
} catch (error) {
|
|
|
|
return reject(error);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2022-12-19 06:09:30 +08:00
|
|
|
const hasTurnServer = () => {
|
|
|
|
return HAS_SEEN_TURN_SERVER;
|
|
|
|
}
|
|
|
|
|
2020-05-21 12:20:46 +08:00
|
|
|
export {
|
|
|
|
fetchStunTurnServers,
|
|
|
|
fetchWebRTCMappedStunTurnServers,
|
|
|
|
getFallbackStun,
|
|
|
|
getMappedFallbackStun,
|
2022-12-19 06:09:30 +08:00
|
|
|
hasTurnServer,
|
2020-05-21 12:20:46 +08:00
|
|
|
};
|