Selkies
Developer Referencewebrtc_utils

HMACRTCMonitor

Periodically regenerates HMAC TURN credentials before they expire.

Rebuilds the config every period seconds on the running event loop and delivers it through the on_rtc_config callback, which the consumer must assign before start().

Attributes

attributeturn_host
= turn_host
attributeturn_port
= turn_port
attributeturn_username
= turn_username
attributeturn_shared_secret
= turn_shared_secret
attributeturn_protocol
= turn_protocol
attributeturn_tls
= turn_tls
attributestun_host
= stun_host
attributestun_port
= stun_port
attributeperiod
= period
attributeenabled
= enabled
attributestop_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_host, turn_port, turn_shared_secret, turn_username, turn_protocol='udp', turn_tls=False, stun_host=None, stun_port=None, period=60, enabled=True)
Source Code
def __init__(
    self,
    turn_host: str,
    turn_port: str,
    turn_shared_secret: str,
    turn_username: str,
    turn_protocol: str = 'udp',
    turn_tls: bool = False,
    stun_host: Optional[str] = None,
    stun_port: Optional[str] = None,
    period: int = 60,
    enabled: bool = True
):
    self.turn_host = turn_host
    self.turn_port = turn_port
    self.turn_username = turn_username
    self.turn_shared_secret = turn_shared_secret
    self.turn_protocol = turn_protocol
    self.turn_tls = turn_tls
    self.stun_host = stun_host
    self.stun_port = stun_port
    self.period = period
    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")
paramself
paramturn_hoststr
paramturn_portstr
paramturn_shared_secretstr
paramturn_usernamestr
paramturn_protocolstr
= 'udp'
paramturn_tlsbool
= False
paramstun_hostOptional[str]
= None
paramstun_portOptional[str]
= None
paramperiodint
= 60
paramenabledbool
= True

Returns

None
funcstart(self) -> None

Starts 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("HMAC RTC monitor started")
paramself

Returns

None
func_monitor_loop(self) -> None

Regenerates and dispatches credentials until stopped.

The HMAC generation and config parsing run in worker threads so the loop stays responsive; per-iteration failures are logged and retried on the next period rather than killing the monitor.

Source Code
async def _monitor_loop(self) -> None:
    """Regenerates and dispatches credentials until stopped.

    The HMAC generation and config parsing run in worker threads so the
    loop stays responsive; per-iteration failures are logged and retried
    on the next period rather than killing the monitor.
    """
    try:
        while not self.stop_event.is_set():
            try:
                hmac_data = await asyncio.to_thread(
                    generate_rtc_config,
                    self.turn_host,
                    self.turn_port,
                    self.turn_shared_secret,
                    self.turn_username,
                    self.turn_protocol,
                    self.turn_tls,
                    self.stun_host,
                    self.stun_port)
                stun_servers, turn_servers, rtc_config = await asyncio.to_thread(parse_rtc_config, hmac_data)
                await _dispatch_rtc_callback(self.on_rtc_config, stun_servers, turn_servers, rtc_config)
            except Exception as e:
                logger_rtcice.warning(f"could not fetch TURN HMAC config in periodic monitor: {e}")

            try:
                await asyncio.wait_for(self.stop_event.wait(), timeout=self.period)
            except asyncio.TimeoutError:
                pass
    except asyncio.CancelledError:
        pass
    except Exception as e:
        logger_rtcice.error(f"Error in HMAC RTC monitor: {e}")
    finally:
        logger_rtcice.info("HMAC RTC monitor stopped")
paramself

Returns

None
funcstop(self) -> None

Signals 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._task
paramself

Returns

None

On this page

Edit on GitHub