Developer Referencewebrtc_utils
CloudflareRTCMonitor
Refreshes Cloudflare TURN credentials before their TTL (default 24h) expires.
Delivers each refreshed config through the on_rtc_config callback, which
the consumer must assign before start(). period defaults to half the
TTL (at least a minute) so a refresh lands well within the credential
lifetime.
Attributes
attributeturn_token_id= turn_token_idattributeapi_token= api_tokenattributettl= ttlattributeperiod= period if period is not None else max(60, ttl // 2)attributeenabled= enabledattributestop_event= asyncio.Event()attributeon_rtc_configCallable[[List[str], List[str], bytes], Any]= lambda stun_servers, turn_servers, rtc_config: logger_rtcice.warning('unhandled on_rtc_config')Functions
func__init__(self, turn_token_id, api_token, ttl=86400, period=None, enabled=True)Source Code
def __init__(
self,
turn_token_id: str,
api_token: str,
ttl: int = 86400,
period: Optional[int] = None,
enabled: bool = True
):
self.turn_token_id = turn_token_id
self.api_token = api_token
self.ttl = ttl
self.period = period if period is not None else max(60, ttl // 2)
self.enabled = enabled
self.stop_event = asyncio.Event()
self._task: Optional[asyncio.Task] = None
self.on_rtc_config: Callable[[List[str], List[str], bytes], Any] = lambda stun_servers, turn_servers, rtc_config: logger_rtcice.warning("unhandled on_rtc_config")paramselfparamturn_token_idstrparamapi_tokenstrparamttlint= 86400paramperiodOptional[int]= Noneparamenabledbool= TrueReturns
Nonefuncstart(self) -> NoneStarts the periodic refresh task; no-op when disabled.
Source Code
def start(self) -> None:
"""Starts the periodic refresh task; no-op when disabled."""
if not self.enabled:
return
self.stop_event.clear()
self._task = asyncio.create_task(self._monitor_loop())
logger_rtcice.info("Cloudflare TURN RTC monitor started")paramselfReturns
Nonefunc_monitor_loop(self) -> NoneRefreshes and dispatches Cloudflare credentials until stopped.
Each iteration waits a period before fetching: the initial credentials
were already fetched at startup by get_rtc_configuration.
Source Code
async def _monitor_loop(self) -> None:
"""Refreshes and dispatches Cloudflare credentials until stopped.
Each iteration waits a period before fetching: the initial credentials
were already fetched at startup by `get_rtc_configuration`.
"""
try:
while not self.stop_event.is_set():
try:
await asyncio.wait_for(self.stop_event.wait(), timeout=self.period)
break
except asyncio.TimeoutError:
pass
try:
json_config = await fetch_cloudflare_turn(self.turn_token_id, self.api_token, self.ttl)
wrapped_config = json.dumps({"iceServers": [json_config["iceServers"]]})
stun_servers, turn_servers, rtc_config = parse_rtc_config(wrapped_config)
await _dispatch_rtc_callback(self.on_rtc_config, stun_servers, turn_servers, rtc_config)
except Exception as e:
logger_rtcice.warning(f"could not refresh Cloudflare TURN config in periodic monitor: {e}")
except asyncio.CancelledError:
pass
except Exception as e:
logger_rtcice.error(f"Error in Cloudflare TURN RTC monitor: {e}")
finally:
logger_rtcice.info("Cloudflare TURN RTC monitor stopped")paramselfReturns
Nonefuncstop(self) -> NoneSignals the loop to exit and waits for the task to finish.
Source Code
async def stop(self) -> None:
"""Signals the loop to exit and waits for the task to finish."""
self.stop_event.set()
if self._task:
await self._taskparamselfReturns
None