vroom-web-sdk-beta
Version:
VROOM SDK (beta) by True Virtual World
171 lines (129 loc) • 4.36 kB
text/typescript
import randomString from '../helpers/randomString.helper'
import { sdkVersion } from '../constants'
import VroomPlugin from '../plugins/vroom.plugin'
import { Transaction, CallbackTransaction, TransactionEnum } from '../types/message'
import { BaseTransaction, HeartBeat, DestroySession } from '../types/vroomRequest'
import Bowser from 'bowser'
import VroomVideoPlugin from '../plugins/vroom-video.plugin'
interface VroomSessionInterface {
ws: WebSocket
transactions: { [id: string]: any }
plugins: { [id: string]: VroomPlugin }
}
class VroomSession implements VroomSessionInterface {
ws: WebSocket
transactions: Map<string, Transaction> = new Map()
plugins: { [id: string]: any } = {}
connected: boolean = true
sessionId!: number
keepAliveTimeoutID: any = null
private clientObj: { [id: string]: any } = {}
constructor(_ws: WebSocket, sessionId: number) {
this.ws = _ws
const browser = Bowser.getParser(window.navigator.userAgent)
this.clientObj = {
client_id: randomString(8),
client_info: {
platform: browser.getPlatform(),
app_version: sdkVersion,
os_version: browser.getOSVersion(),
model: browser.getBrowserName(),
},
}
this.sessionId = sessionId
this.setOnMessage()
}
attachPlugin = (plugin: VroomVideoPlugin) => {
this.plugins[plugin.handleId!!] = plugin
}
deletePlugin = (plugin: VroomVideoPlugin) => {
delete this.plugins[plugin.handleId!!]
}
destroy = async (sessionId: any) => {
try {
this.connected = false
clearTimeout(this.keepAliveTimeoutID)
await this.sendAsync(new DestroySession({ session_id: sessionId }))
this.ws.close()
} catch (e) {
console.error('destroy janus', e)
}
this.ws.close()
}
setOnMessage() {
this.ws.onmessage = async (e) => {
try {
const message = JSON.parse(e.data)
if (message.janus === 'event') {
if (message.transaction) {
const { transaction } = message
await this.executeTransaction(transaction, message)
return
}
return await this.plugins[message.sender].onMessage(message)
} else if (message.janus === 'error' && message.transaction) {
const { transaction } = message
await this.executeTransaction(transaction, message)
return
}
if (message.janus && message.janus !== 'ack' && message.transaction) {
const { transaction } = message
await this.executeTransaction(transaction, message)
} else if (message.sender && this.plugins[message.sender]) {
await this.plugins[message.sender].onMessage(message)
}
} catch (e) {
console.error('ERROR ', e)
}
}
}
private send(request: BaseTransaction, callback?: CallbackTransaction, transaction?: string) {
if (!transaction && callback) {
const t = this.generateTransaction(callback)
transaction = t.transactionId
this.transactions.set(transaction, t)
}
request.transaction = transaction
request.body = { ...request.body, client_id: this.clientObj.client_id, client_info: this.clientObj.client_info }
this.ws.send(JSON.stringify(request))
}
sendAsync(request: any) {
return new Promise((resolve, reject) => {
this.send(request, async (response: any) => {
if (response.janus !== 'error') {
resolve(response)
} else {
reject(response)
}
})
})
}
private generateTransaction(cb: CallbackTransaction): Transaction {
return {
transactionId: randomString(12),
type: TransactionEnum.attach,
callback: cb,
}
}
private async executeTransaction(transaction: string, message: any) {
const _transaction = this.transactions.get(transaction)
if (_transaction) {
await _transaction.callback(message)
}
this.transactions.delete(transaction)
}
private keepAlive() {
if (this.connected) {
this.setKeepAliveTimeout()
this.sendAsync(new HeartBeat({
session_id: this.sessionId,
})).catch(console.error)
}
}
setKeepAliveTimeout() {
if (this.connected) {
this.keepAliveTimeoutID = setTimeout(() => this.keepAlive(), 25000)
}
}
}
export default VroomSession