diff --git a/openvidu-testapp/src/app/components/openvidu-instance/openvidu-instance.component.css b/openvidu-testapp/src/app/components/openvidu-instance/openvidu-instance.component.css index f924ce62f..d5642c47f 100644 --- a/openvidu-testapp/src/app/components/openvidu-instance/openvidu-instance.component.css +++ b/openvidu-testapp/src/app/components/openvidu-instance/openvidu-instance.component.css @@ -182,4 +182,22 @@ mat-checkbox { mat-checkbox:first-of-type { margin-left: 0; -} \ No newline at end of file +} + +/* WebSocket blocking button styles */ +.ws-block-btn { + color: #ff9800 !important; +} + +.ws-block-btn:hover { + color: #f57c00 !important; +} + +.ws-block-persistent-btn { + color: #f44336 !important; +} + +.ws-block-persistent-btn:hover { + color: #d32f2f !important; +} + diff --git a/openvidu-testapp/src/app/components/openvidu-instance/openvidu-instance.component.html b/openvidu-testapp/src/app/components/openvidu-instance/openvidu-instance.component.html index baf68e487..59b4ee5f6 100644 --- a/openvidu-testapp/src/app/components/openvidu-instance/openvidu-instance.component.html +++ b/openvidu-testapp/src/app/components/openvidu-instance/openvidu-instance.component.html @@ -124,9 +124,15 @@ - + + diff --git a/openvidu-testapp/src/app/components/openvidu-instance/openvidu-instance.component.ts b/openvidu-testapp/src/app/components/openvidu-instance/openvidu-instance.component.ts index 87d7a43ed..d178ff5a4 100644 --- a/openvidu-testapp/src/app/components/openvidu-instance/openvidu-instance.component.ts +++ b/openvidu-testapp/src/app/components/openvidu-instance/openvidu-instance.component.ts @@ -161,6 +161,9 @@ export class OpenviduInstanceComponent implements OnInit, OnChanges, OnDestroy { republishPossible: boolean = false; openviduError: any; + // WebSocket blocking state + private originalWebSocketCtor: typeof WebSocket; + constructor( private changeDetector: ChangeDetectorRef, private dialog: MatDialog, @@ -288,11 +291,79 @@ export class OpenviduInstanceComponent implements OnInit, OnChanges, OnDestroy { this.subscribers = []; } - private async simulateNetworkDrop(): Promise { + async simulateNetworkDropGracefully(): Promise { const jsonRpClient = this.OV.session.localParticipant.engine; await jsonRpClient.close(); } + /** + * Block the WebSocket connection by closing it immediately. + * This simulates a transient network failure that may trigger reconnection. + */ + async simulateNetworkDropIntermittently(): Promise { + if (!this.session) { + console.log('[WebSocket] No active session'); + return; + } + + try { + const signalClient = this.OV.session.localParticipant.engine.client; + if (!signalClient || !signalClient.ws) { + console.log('[WebSocket] Could not access WebSocket connection'); + return; + } + + signalClient.ws.close(); + console.log('[WebSocket] Closed once (quick reconnect expected)'); + } catch (error) { + console.error('[WebSocket] blockWebSocket error:', error); + } + } + + /** + * Block WebSocket connections persistently by replacing the WebSocket constructor. + * All new socket connection attempts will be immediately closed. + * This simulates a persistent network blocking condition. + */ + async simulateHardNetworkDrop(): Promise { + if (!this.session) { + console.log('[WebSocket] No active session'); + return; + } + + // Close current WebSocket if exists + try { + const signalClient = this.OV.session.localParticipant.engine.client; + if (signalClient && signalClient.ws) { + console.log('[WebSocket] Closing current WebSocket...'); + signalClient.ws.close({ closeCode: 1000, reason: 'Simulating persistent WebSocket block' }); + } + } catch (error) { + console.error('[WebSocket] Error closing current WebSocket:', error); + } + + // Replace WebSocket constructor to block new connections + this.originalWebSocketCtor = window.WebSocket; + console.log('[WebSocket] Enabling persistent WebSocket block...'); + + const self = this; + (window as any).WebSocket = class BlockedWebSocket { + constructor(url: string | URL, protocols?: string | string[]) { + const wsInstance = new self.originalWebSocketCtor(url, protocols); + // Check if it's a signal WebSocket and block it + const urlStr = String(url).toLowerCase(); + if (urlStr.startsWith('ws://') || urlStr.startsWith('wss://')) { + setTimeout(() => { + if (wsInstance.readyState === 0 || wsInstance.readyState === 1) { + wsInstance.close(4000, 'Simulated persistent WebSocket block'); + } + }, 0); + } + return wsInstance; + } + } as typeof WebSocket; + } + updateEventList(eventName: string, eventContent: string, event: Event) { const eventInterface: OpenViduEvent = { eventName, eventContent, event }; this.events.push(eventInterface);