import { merge } from '../../utils/config' ; const WEBSOCKET_TIMEOUT = 10007 ; export interface WSConfig { host ? : string ; scheme ? : string ; uri ? : string ; tokenUri ? : string ; protocol ? : string ; timeout ? : number ; } const defaultConfig = ( host = window . location . host , scheme = window . location . protocol ) : WSConfig => { const wsScheme = scheme === 'https:' ? 'wss:' : 'ws:' ; return { uri : `${ wsScheme }//${ host }/rtsp-over-websocket` , tokenUri : `${ scheme }//${ host }/axis-cgi/rtspwssession.cgi` , protocol : 'binary' , timeout : WEBSOCKET_TIMEOUT , } ; } ; param config param config . host param config . sheme param config . uri param config . tokenUri param config . protocol param config . timeout export const openWebSocket = async ( config = { } ) : Promise < WebSocket > => { const { uri , tokenUri , protocol , timeout } = merge ( defaultConfig ( config . host , config . scheme ) , config ) ; if ( uri === undefined ) { throw new Error ( 'ws: internal error' ) ; } return await new Promise ( ( resolve , reject ) => { try { const ws = new WebSocket ( uri , protocol ) ; const countdown = setTimeout ( ( ) => { clearTimeout ( countdown ) ; if ( ws . readyState === WebSocket . CONNECTING ) { ws . onerror = null ; reject ( new Error ( 'websocket connection timed out' ) ) ; } } , timeout ) ; ws . binaryType = 'arraybuffer' ; ws . onerror = ( originalError ) => { clearTimeout ( countdown ) ; function onLoadToken ( this ) { if ( this . status >= 400 ) { console . warn ( 'failed to load token' , this . status , this . responseText ) ; reject ( originalError ) ; return ; } const token = this . responseText . trim ( ) ; const newUri = `${ uri }?rtspwssession=${ token }` ; const ws2 = new WebSocket ( newUri , protocol ) ; ws2 . binaryType = 'arraybuffer' ; ws2 . onerror = ( err ) => { reject ( err ) ; } ; ws2 . onopen = ( ) => resolve ( ws2 ) ; } const request = new XMLHttpRequest ( ) ; request . addEventListener ( 'load' , onLoadToken ) ; request . addEventListener ( 'error' , ( err ) => { console . warn ( 'failed to get token' ) ; reject ( err ) ; } ) ; request . addEventListener ( 'abort' , ( ) => reject ( originalError ) ) ; request . open ( 'GET' , `${ tokenUri }?${ Date . now ( ) }` ) ; try { request . send ( ) ; } catch ( error ) { reject ( originalError ) ; } } ; ws . onopen = ( ) => { clearTimeout ( countdown ) ; resolve ( ws ) ; } ; } catch ( e ) { reject ( e ) ; } } ) ; } ;