feat(web): второй ряд дашборда и пинг участников в голосовой комнате
- дашборд инстанса: два ряда полукругов с подписями сверху — «Контейнер инстанса» (лимиты профиля) и «Сервер целиком» (вся машина); - голосовая комната: рядом с качеством связи видно пинг участника («Отличное соединение, 42 мс») и он обновляется раз в секунду. Свой RTT измеряется по статистике WebRTC, чужой приходит по data-каналу LiveKit (`glchat.latency`, lossy), поэтому пинг виден для каждого участника; - статистика берётся с любой своей дорожки: в аудио-сессии RTT раньше был недоступен (отчёт читался только с видео); - в «Аудио-видео» появился тумблер «Показывать пинг в голосовой комнате»: выключенный не опрашивает SDK и не публикует своё значение; - тесты: ряд хоста и подписи, пинг в плитке своего и чужого участника, публикация по служебной теме, выключенный пинг не дёргает SDK.
This commit is contained in:
@@ -21,6 +21,7 @@ export const RoomEvent = {
|
||||
Reconnecting: 'reconnecting',
|
||||
Reconnected: 'reconnected',
|
||||
Disconnected: 'disconnected',
|
||||
DataReceived: 'dataReceived',
|
||||
} as const;
|
||||
|
||||
export const ConnectionQuality = {
|
||||
@@ -106,6 +107,8 @@ export class FakeParticipant {
|
||||
readonly isLocal: boolean;
|
||||
/** Вызовы, которые проверяют тесты: `setMicrophoneEnabled(false)` и т.п. */
|
||||
readonly calls: { method: string; value: unknown }[] = [];
|
||||
/** Отправленные data-пакеты: `{ payload, options }` каждого publishData. */
|
||||
readonly data: { payload: Uint8Array; options: unknown }[] = [];
|
||||
/** Параметры захвата экрана: `{ enabled, options }` каждого вызова. */
|
||||
readonly screenOptions: { enabled: boolean; options: unknown }[] = [];
|
||||
private readonly publications = new Map<string, FakePublication>();
|
||||
@@ -156,6 +159,12 @@ export class FakeParticipant {
|
||||
this.room.emit(RoomEvent.TrackUnsubscribed);
|
||||
}
|
||||
|
||||
/** Отправка data-сообщения: тесты проверяют тему, payload и надёжность. */
|
||||
publishData(payload: Uint8Array, options?: unknown): Promise<void> {
|
||||
this.data.push({ payload, options });
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
setSpeaking(speaking: boolean): void {
|
||||
this.isSpeaking = speaking;
|
||||
}
|
||||
@@ -238,6 +247,11 @@ export class FakeRoom {
|
||||
this.stats = entries;
|
||||
}
|
||||
|
||||
/** Эмуляция входящего data-пакета: событие `DataReceived` от участника. */
|
||||
emitData(payload: Uint8Array, participant: FakeParticipant, topic: string): void {
|
||||
this.emit(RoomEvent.DataReceived, payload, participant, undefined, topic);
|
||||
}
|
||||
|
||||
on(event: string, handler: Handler): this {
|
||||
const handlers = this.handlers.get(event) ?? new Set<Handler>();
|
||||
handlers.add(handler);
|
||||
|
||||
Reference in New Issue
Block a user