reconnecter: fallback events.

This commit is contained in:
Miroslav Šedivý 2021-07-17 16:36:56 +02:00
parent fc031c16d4
commit b403993fce
4 changed files with 45 additions and 16 deletions

View File

@ -101,9 +101,6 @@ export class NekoConnection extends EventEmitter<NekoConnectionEvents> {
state.webrtc.config, state.webrtc.config,
) )
// initial state
Vue.set(this._state, 'type', 'screencast')
// websocket // websocket
this._websocket_reconn.on('connect', () => { this._websocket_reconn.on('connect', () => {
if (this.websocket.connected && this.webrtc.connected) { if (this.websocket.connected && this.webrtc.connected) {
@ -136,7 +133,7 @@ export class NekoConnection extends EventEmitter<NekoConnectionEvents> {
Vue.set(this._state, 'status', 'connecting') Vue.set(this._state, 'status', 'connecting')
} }
Vue.set(this._state, 'type', 'screencast') Vue.set(this._state, 'type', 'fallback')
}) })
this._webrtc_reconn.on('close', (error) => { this._webrtc_reconn.on('close', (error) => {
this.disconnect(error) this.disconnect(error)
@ -157,10 +154,18 @@ export class NekoConnection extends EventEmitter<NekoConnectionEvents> {
// check if video is not playing smoothly // check if video is not playing smoothly
if (stats.fps && stats.packetLoss < WEBRTC_RECONN_MAX_LOSS && !stats.muted) { if (stats.fps && stats.packetLoss < WEBRTC_RECONN_MAX_LOSS && !stats.muted) {
if (this._state.type === 'fallback') {
Vue.set(this._state, 'type', 'webrtc')
}
webrtcCongestion = 0 webrtcCongestion = 0
return return
} }
if (this._state.type === 'webrtc') {
Vue.set(this._state, 'type', 'fallback')
}
// try to downgrade quality if it happend many times // try to downgrade quality if it happend many times
if (++webrtcCongestion >= WEBRTC_RECONN_FAILED_ATTEMPTS) { if (++webrtcCongestion >= WEBRTC_RECONN_FAILED_ATTEMPTS) {
webrtcCongestion = 0 webrtcCongestion = 0
@ -205,7 +210,9 @@ export class NekoConnection extends EventEmitter<NekoConnectionEvents> {
Vue.set(this._state.webrtc, 'video', video) Vue.set(this._state.webrtc, 'video', video)
} }
Vue.set(this._state, 'type', 'fallback')
Vue.set(this._state, 'status', 'connecting') Vue.set(this._state, 'status', 'connecting')
this._webrtc_reconn.open(true) this._webrtc_reconn.open(true)
this._websocket_reconn.open() this._websocket_reconn.open()
} }
@ -214,7 +221,9 @@ export class NekoConnection extends EventEmitter<NekoConnectionEvents> {
this._websocket_reconn.close() this._websocket_reconn.close()
this._webrtc_reconn.close() this._webrtc_reconn.close()
Vue.set(this._state, 'type', 'none')
Vue.set(this._state, 'status', 'disconnected') Vue.set(this._state, 'status', 'disconnected')
this.emit('disconnect', error) this.emit('disconnect', error)
} }

View File

@ -1,14 +1,8 @@
<template> <template>
<div ref="component" class="neko-component"> <div ref="component" class="neko-component">
<div ref="container" class="neko-container"> <div ref="container" class="neko-container">
<video <video v-show="!screencast" ref="video" :autoplay="autoplay" :muted="autoplay" playsinline />
v-show="state.connection.type == 'webrtc'" <neko-screencast v-show="screencast" :enabled="screencast" :api="api.room" />
ref="video"
:autoplay="autoplay"
:muted="autoplay"
playsinline
/>
<neko-screencast v-if="state.connection.type == 'screencast' && state.connection.screencast" :api="api.room" />
<neko-overlay <neko-overlay
:webrtc="connection.webrtc" :webrtc="connection.webrtc"
:scroll="state.control.scroll" :scroll="state.control.scroll"
@ -182,6 +176,10 @@
return this.state.session_id != null ? this.state.sessions[this.state.session_id].profile.is_admin : false return this.state.session_id != null ? this.state.sessions[this.state.session_id].profile.is_admin : false
} }
public get screencast() {
return this.state.connection.type == 'fallback' && this.state.connection.screencast
}
///////////////////////////// /////////////////////////////
// Public events // Public events
///////////////////////////// /////////////////////////////

View File

@ -15,6 +15,9 @@
@Ref('image') readonly _image!: HTMLImageElement @Ref('image') readonly _image!: HTMLImageElement
active = false active = false
@Prop()
private readonly enabled!: boolean
@Prop() @Prop()
private readonly api!: RoomApi private readonly api!: RoomApi
@ -36,18 +39,37 @@
} }
} }
async mounted() { mounted() {
if (this.enabled) {
this.start()
}
}
beforeDestroy() {
this.stop()
}
start() {
this.active = true this.active = true
setTimeout(this.loop, 0) setTimeout(this.loop, 0)
} }
beforeDestroy() { stop() {
this.active = false this.active = false
if (this._image.src) { if (this._image && this._image.src) {
URL.revokeObjectURL(this._image.src) URL.revokeObjectURL(this._image.src)
} }
} }
@Watch('enabled')
onEnabledChanged(enabled: boolean) {
if (enabled) {
this.start()
} else {
this.stop()
}
}
} }
</script> </script>

View File

@ -22,7 +22,7 @@ export interface Connection {
websocket: WebSocket websocket: WebSocket
webrtc: WebRTC webrtc: WebRTC
screencast: boolean screencast: boolean
type: 'webrtc' | 'screencast' | 'none' type: 'webrtc' | 'fallback' | 'none'
} }
export interface WebSocket { export interface WebSocket {