mirror of
https://github.com/m1k1o/neko.git
synced 2024-07-24 14:40:50 +12:00
add new reconnection logic.
This commit is contained in:
parent
071f97fb1b
commit
3d1b92ae1c
@ -1,5 +1,6 @@
|
|||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
import EventEmitter from 'eventemitter3'
|
import EventEmitter from 'eventemitter3'
|
||||||
|
import { Logger } from '../utils/logger'
|
||||||
import * as EVENT from '../types/events'
|
import * as EVENT from '../types/events'
|
||||||
|
|
||||||
import { NekoWebSocket } from './websocket'
|
import { NekoWebSocket } from './websocket'
|
||||||
@ -14,6 +15,8 @@ export class NekoConnection extends EventEmitter<NekoConnectionEvents> {
|
|||||||
private _url: string
|
private _url: string
|
||||||
private _token: string
|
private _token: string
|
||||||
private _state: Connection
|
private _state: Connection
|
||||||
|
private _log: Logger
|
||||||
|
private _shouldReconnect = false
|
||||||
|
|
||||||
public websocket = new NekoWebSocket()
|
public websocket = new NekoWebSocket()
|
||||||
public webrtc = new NekoWebRTC()
|
public webrtc = new NekoWebRTC()
|
||||||
@ -23,52 +26,48 @@ export class NekoConnection extends EventEmitter<NekoConnectionEvents> {
|
|||||||
|
|
||||||
this._url = ''
|
this._url = ''
|
||||||
this._token = ''
|
this._token = ''
|
||||||
|
this._log = new Logger('connection')
|
||||||
this._state = state
|
this._state = state
|
||||||
|
|
||||||
// initial state
|
// initial state
|
||||||
Vue.set(this._state, 'type', 'webrtc')
|
Vue.set(this._state, 'type', 'webrtc')
|
||||||
|
|
||||||
let webSocketStatus = 'disconnected'
|
|
||||||
let webRTCStatus = 'disconnected'
|
|
||||||
|
|
||||||
// websocket
|
// websocket
|
||||||
this.websocket.on('connecting', () => {
|
this.websocket.on('connecting', () => {
|
||||||
webSocketStatus = 'connecting'
|
|
||||||
if (this._state.status !== 'connecting') {
|
if (this._state.status !== 'connecting') {
|
||||||
Vue.set(this._state, 'status', 'connecting')
|
Vue.set(this._state, 'status', 'connecting')
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
this.websocket.on('connected', () => {
|
this.websocket.on('connected', () => {
|
||||||
webSocketStatus = 'connected'
|
if (this.websocket.connected && this.webrtc.connected) {
|
||||||
if (webSocketStatus == 'connected' && webRTCStatus == 'connected') {
|
|
||||||
Vue.set(this._state, 'status', 'connected')
|
Vue.set(this._state, 'status', 'connected')
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
this.websocket.on('disconnected', () => {
|
this.websocket.on('disconnected', () => {
|
||||||
webSocketStatus = 'disconnected'
|
|
||||||
if (this._state.status !== 'disconnected') {
|
if (this._state.status !== 'disconnected') {
|
||||||
Vue.set(this._state, 'status', 'disconnected')
|
Vue.set(this._state, 'status', 'disconnected')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this._websocketReconnect()
|
||||||
})
|
})
|
||||||
|
|
||||||
// webrtc
|
// webrtc
|
||||||
this.webrtc.on('connecting', () => {
|
this.webrtc.on('connecting', () => {
|
||||||
webRTCStatus = 'connecting'
|
|
||||||
if (this._state.status !== 'connecting') {
|
if (this._state.status !== 'connecting') {
|
||||||
Vue.set(this._state, 'status', 'connecting')
|
Vue.set(this._state, 'status', 'connecting')
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
this.webrtc.on('connected', () => {
|
this.webrtc.on('connected', () => {
|
||||||
webRTCStatus = 'connected'
|
if (this.websocket.connected && this.webrtc.connected) {
|
||||||
if (webSocketStatus == 'connected' && webRTCStatus == 'connected') {
|
|
||||||
Vue.set(this._state, 'status', 'connected')
|
Vue.set(this._state, 'status', 'connected')
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
this.webrtc.on('disconnected', () => {
|
this.webrtc.on('disconnected', () => {
|
||||||
webRTCStatus = 'disconnected'
|
|
||||||
if (this._state.status !== 'disconnected') {
|
if (this._state.status !== 'disconnected') {
|
||||||
Vue.set(this._state, 'status', 'disconnected')
|
Vue.set(this._state, 'status', 'disconnected')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this._webrtcReconnect()
|
||||||
})
|
})
|
||||||
|
|
||||||
let webrtcCongestion: number = 0
|
let webrtcCongestion: number = 0
|
||||||
@ -123,22 +122,87 @@ export class NekoConnection extends EventEmitter<NekoConnectionEvents> {
|
|||||||
this.websocket.send(EVENT.SIGNAL_VIDEO, { video: video })
|
this.websocket.send(EVENT.SIGNAL_VIDEO, { video: video })
|
||||||
}
|
}
|
||||||
|
|
||||||
public async connect(): Promise<void> {
|
public async connect(video?: string): Promise<void> {
|
||||||
|
this._shouldReconnect = true
|
||||||
|
|
||||||
|
await this._websocketConnect()
|
||||||
|
|
||||||
|
if (video && !this._state.webrtc.videos.includes(video)) {
|
||||||
|
throw new Error('video id not found')
|
||||||
|
}
|
||||||
|
|
||||||
|
this._webrtcConnect(video)
|
||||||
|
}
|
||||||
|
|
||||||
|
public disconnect() {
|
||||||
|
this._shouldReconnect = false
|
||||||
|
|
||||||
|
this.webrtc.disconnect()
|
||||||
|
this.websocket.disconnect()
|
||||||
|
|
||||||
|
Vue.set(this._state, 'status', 'disconnected')
|
||||||
|
this.emit('disconnect')
|
||||||
|
}
|
||||||
|
|
||||||
|
async _websocketConnect() {
|
||||||
let url = this._url
|
let url = this._url
|
||||||
if (this._token) {
|
if (this._token) {
|
||||||
url += '?token=' + encodeURIComponent(this._token)
|
url += '?token=' + encodeURIComponent(this._token)
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.websocket.connect(url)
|
await this.websocket.connect(url)
|
||||||
|
|
||||||
// TODO: connect to WebRTC
|
|
||||||
//this.websocket.send(EVENT.SIGNAL_REQUEST, { video: video })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public disconnect() {
|
_websocketIsReconnecting = false
|
||||||
this.webrtc.disconnect()
|
_websocketReconnect() {
|
||||||
this.websocket.disconnect()
|
if (this._websocketIsReconnecting) {
|
||||||
Vue.set(this._state, 'status', 'disconnected')
|
return
|
||||||
this.emit('disconnect')
|
}
|
||||||
|
|
||||||
|
setTimeout(async () => {
|
||||||
|
while (this._shouldReconnect) {
|
||||||
|
try {
|
||||||
|
await this._websocketConnect()
|
||||||
|
this._webrtcReconnect()
|
||||||
|
break
|
||||||
|
} catch (e) {
|
||||||
|
this._log.debug(`websocket reconnection`, e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this._websocketIsReconnecting = false
|
||||||
|
}, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
_webrtcConnect(video?: string) {
|
||||||
|
if (video && !this._state.webrtc.videos.includes(video)) {
|
||||||
|
throw new Error('video id not found')
|
||||||
|
}
|
||||||
|
|
||||||
|
this.websocket.send(EVENT.SIGNAL_REQUEST, { video: video })
|
||||||
|
}
|
||||||
|
|
||||||
|
_webrtcReconnTimer?: number
|
||||||
|
_webrtcReconnect() {
|
||||||
|
if (this._webrtcReconnTimer) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const lastVideo = this._state.webrtc.video ?? undefined
|
||||||
|
|
||||||
|
const reconnFunc = async () => {
|
||||||
|
if (!this._shouldReconnect || !this.websocket.connected || this.webrtc.connected) {
|
||||||
|
clearInterval(this._webrtcReconnTimer)
|
||||||
|
this._webrtcReconnTimer = undefined
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
this._webrtcConnect(lastVideo)
|
||||||
|
} catch (e) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
this._webrtcReconnTimer = window.setInterval(reconnFunc, 1000)
|
||||||
|
reconnFunc()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -256,13 +256,7 @@
|
|||||||
throw new Error('client is already connected')
|
throw new Error('client is already connected')
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.connection.connect()
|
await this.connection.connect(video)
|
||||||
|
|
||||||
if (video && !this.state.connection.webrtc.videos.includes(video)) {
|
|
||||||
throw new Error('video id not found')
|
|
||||||
}
|
|
||||||
|
|
||||||
this.connection.websocket.send(EVENT.SIGNAL_REQUEST, { video: video })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public disconnect() {
|
public disconnect() {
|
||||||
|
Loading…
Reference in New Issue
Block a user