add messages handler.

This commit is contained in:
Miroslav Šedivý 2020-11-06 23:27:07 +01:00
parent e79734f51e
commit ff7eafd5bd
5 changed files with 545 additions and 1 deletions

View File

@ -46,6 +46,7 @@
import { NekoWebSocket } from '~/internal/websocket' import { NekoWebSocket } from '~/internal/websocket'
import { NekoWebRTC } from '~/internal/webrtc' import { NekoWebRTC } from '~/internal/webrtc'
import { NekoMessages } from '~/internal/messages'
import NekoState from '~/types/state' import NekoState from '~/types/state'
import Overlay from './overlay.vue' import Overlay from './overlay.vue'
@ -64,6 +65,7 @@
private observer = new ResizeObserver(this.onResize.bind(this)) private observer = new ResizeObserver(this.onResize.bind(this))
private websocket = new NekoWebSocket() private websocket = new NekoWebSocket()
private webrtc = new NekoWebRTC() private webrtc = new NekoWebRTC()
private messages = new NekoMessages()
private state = { private state = {
id: null, id: null,
@ -134,7 +136,13 @@
} }
break break
default: default:
console.log(event, payload) // @ts-ignore
if (typeof this.messages[event] === 'function') {
// @ts-ignore
this.messages[event](payload)
} else {
console.log(`unhandled websocket event '${event}':`, payload)
}
} }
}) })
this.websocket.on('connecting', () => { this.websocket.on('connecting', () => {

240
src/internal/messages.ts Normal file
View File

@ -0,0 +1,240 @@
import Vue from 'vue'
import { Member } from '../types/structs'
import { EVENT } from '../types/events'
import {
DisconnectPayload,
SignalProvidePayload,
MemberListPayload,
MemberDisconnectPayload,
MemberPayload,
ControlPayload,
ControlTargetPayload,
ControlClipboardPayload,
ScreenConfigurationsPayload,
ScreenResolutionPayload,
BroadcastStatusPayload,
AdminPayload,
AdminTargetPayload,
} from '../types/messages'
export class NekoMessages {
/////////////////////////////
// System Events
/////////////////////////////
public [EVENT.SYSTEM.DISCONNECT]({ message }: DisconnectPayload) {
console.log('EVENT.SYSTEM.DISCONNECT')
//this.onDisconnected(new Error(message))
//this.$vue.$swal({
// title: this.$vue.$t('connection.disconnected'),
// text: message,
// icon: 'error',
// confirmButtonText: this.$vue.$t('connection.button_confirm') as string,
//})
}
/////////////////////////////
// Member Events
/////////////////////////////
public [EVENT.MEMBER.LIST]({ members }: MemberListPayload) {
console.log('EVENT.MEMBER.LIST')
//this.$accessor.user.setMembers(members)
}
public [EVENT.MEMBER.CONNECTED](member: MemberPayload) {
console.log('EVENT.MEMBER.CONNECTED')
//this.$accessor.user.addMember(member)
}
public [EVENT.MEMBER.DISCONNECTED]({ id }: MemberDisconnectPayload) {
console.log('EVENT.MEMBER.DISCONNECTED')
//const member = this.member(id)
//if (!member) {
// return
//}
//
//this.$accessor.user.delMember(id)
}
/////////////////////////////
// Control Events
/////////////////////////////
public [EVENT.CONTROL.LOCKED]({ id }: ControlPayload) {
console.log('EVENT.CONTROL.LOCKED')
//this.$accessor.remote.setHost(id)
//this.$accessor.remote.changeKeyboard()
//
//const member = this.member(id)
//if (!member) {
// return
//}
//
//if (this.id === id) {
// this.$vue.$notify({
// group: 'neko',
// type: 'info',
// title: this.$vue.$t('notifications.controls_taken', { name: this.$vue.$t('you') }) as string,
// duration: 5000,
// speed: 1000,
// })
//}
}
public [EVENT.CONTROL.RELEASE]({ id }: ControlPayload) {
console.log('EVENT.CONTROL.RELEASE')
//this.$accessor.remote.reset()
//const member = this.member(id)
//if (!member) {
// return
//}
//
//if (this.id === id) {
// this.$vue.$notify({
// group: 'neko',
// type: 'info',
// title: this.$vue.$t('notifications.controls_released', { name: this.$vue.$t('you') }) as string,
// duration: 5000,
// speed: 1000,
// })
//}
}
public [EVENT.CONTROL.REQUEST]({ id }: ControlPayload) {
console.log('EVENT.CONTROL.REQUEST')
//const member = this.member(id)
//if (!member) {
// return
//}
//
//this.$vue.$notify({
// group: 'neko',
// type: 'info',
// title: this.$vue.$t('notifications.controls_has', { name: member.displayname }) as string,
// text: this.$vue.$t('notifications.controls_has_alt') as string,
// duration: 5000,
// speed: 1000,
//})
}
public [EVENT.CONTROL.REQUESTING]({ id }: ControlPayload) {
console.log('EVENT.CONTROL.REQUESTING')
//const member = this.member(id)
//if (!member || member.ignored) {
// return
//}
//
//this.$vue.$notify({
// group: 'neko',
// type: 'info',
// title: this.$vue.$t('notifications.controls_requesting', { name: member.displayname }) as string,
// duration: 5000,
// speed: 1000,
//})
}
public [EVENT.CONTROL.GIVE]({ id, target }: ControlTargetPayload) {
console.log('EVENT.CONTROL.GIVE')
//const member = this.member(target)
//if (!member) {
// return
//}
//
//this.$accessor.remote.setHost(member)
//this.$accessor.remote.changeKeyboard()
}
public [EVENT.CONTROL.CLIPBOARD]({ text }: ControlClipboardPayload) {
console.log('EVENT.CONTROL.CLIPBOARD')
//this.$accessor.remote.setClipboard(text)
}
/////////////////////////////
// Screen Events
/////////////////////////////
public [EVENT.SCREEN.CONFIGURATIONS]({ configurations }: ScreenConfigurationsPayload) {
console.log('EVENT.SCREEN.CONFIGURATIONS')
//this.$accessor.video.setConfigurations(configurations)
}
public [EVENT.SCREEN.RESOLUTION]({ id, width, height, rate }: ScreenResolutionPayload) {
console.log('EVENT.SCREEN.RESOLUTION')
//this.$accessor.video.setResolution({ width, height, rate })
}
/////////////////////////////
// Broadcast Events
/////////////////////////////
public [EVENT.BROADCAST.STATUS](payload: BroadcastStatusPayload) {
console.log('EVENT.BROADCAST.STATUS')
//this.$accessor.settings.broadcastStatus(payload)
}
/////////////////////////////
// Admin Events
/////////////////////////////
public [EVENT.ADMIN.BAN]({ id, target }: AdminTargetPayload) {
console.log('EVENT.ADMIN.BAN')
// TODO
}
public [EVENT.ADMIN.KICK]({ id, target }: AdminTargetPayload) {
console.log('EVENT.ADMIN.KICK')
// TODO
}
public [EVENT.ADMIN.MUTE]({ id, target }: AdminTargetPayload) {
console.log('EVENT.ADMIN.MUTE')
//if (!target) {
// return
//}
//
//this.$accessor.user.setMuted({ id: target, muted: true })
}
public [EVENT.ADMIN.UNMUTE]({ id, target }: AdminTargetPayload) {
console.log('EVENT.ADMIN.UNMUTE')
//if (!target) {
// return
//}
//
//this.$accessor.user.setMuted({ id: target, muted: false })
}
public [EVENT.ADMIN.LOCK]({ id }: AdminPayload) {
console.log('EVENT.ADMIN.LOCK')
//this.$accessor.setLocked(true)
}
public [EVENT.ADMIN.UNLOCK]({ id }: AdminPayload) {
console.log('EVENT.ADMIN.UNLOCK')
//this.$accessor.setLocked(false)
}
public [EVENT.ADMIN.CONTROL]({ id, target }: AdminTargetPayload) {
console.log('EVENT.ADMIN.CONTROL')
//this.$accessor.remote.setHost(id)
//this.$accessor.remote.changeKeyboard()
}
public [EVENT.ADMIN.RELEASE]({ id, target }: AdminTargetPayload) {
console.log('EVENT.ADMIN.RELEASE')
//this.$accessor.remote.reset()
}
public [EVENT.ADMIN.GIVE]({ id, target }: AdminTargetPayload) {
console.log('EVENT.ADMIN.GIVE')
//if (!target) {
// return
//}
//
//const member = this.member(target)
//if (member) {
// this.$accessor.remote.setHost(member)
// this.$accessor.remote.changeKeyboard()
//}
}
// Utilities
//public member(id: string): Member | undefined {
// return this.$accessor.user.members[id]
//}
}

87
src/types/events.ts Normal file
View File

@ -0,0 +1,87 @@
export const EVENT = {
SYSTEM: {
DISCONNECT: 'system/disconnect',
},
SIGNAL: {
ANSWER: 'signal/answer',
PROVIDE: 'signal/provide',
},
MEMBER: {
LIST: 'member/list',
CONNECTED: 'member/connected',
DISCONNECTED: 'member/disconnected',
},
CONTROL: {
LOCKED: 'control/locked',
RELEASE: 'control/release',
REQUEST: 'control/request',
REQUESTING: 'control/requesting',
CLIPBOARD: 'control/clipboard',
GIVE: 'control/give',
KEYBOARD: 'control/keyboard',
},
SCREEN: {
CONFIGURATIONS: 'screen/configurations',
RESOLUTION: 'screen/resolution',
SET: 'screen/set',
},
BROADCAST: {
STATUS: 'broadcast/status',
CREATE: 'broadcast/create',
DESTROY: 'broadcast/destroy',
},
ADMIN: {
BAN: 'admin/ban',
KICK: 'admin/kick',
LOCK: 'admin/lock',
UNLOCK: 'admin/unlock',
MUTE: 'admin/mute',
UNMUTE: 'admin/unmute',
CONTROL: 'admin/control',
RELEASE: 'admin/release',
GIVE: 'admin/give',
},
} as const
export type Events = typeof EVENT
export type WebSocketEvents =
| SystemEvents
| SignalEvents
| MemberEvents
| ControlEvents
| ScreenEvents
| BroadcastEvents
| AdminEvents
export type SystemEvents = typeof EVENT.SYSTEM.DISCONNECT
export type SignalEvents = typeof EVENT.SIGNAL.ANSWER | typeof EVENT.SIGNAL.PROVIDE
export type MemberEvents = typeof EVENT.MEMBER.LIST | typeof EVENT.MEMBER.CONNECTED | typeof EVENT.MEMBER.DISCONNECTED
export type ControlEvents =
| typeof EVENT.CONTROL.LOCKED
| typeof EVENT.CONTROL.RELEASE
| typeof EVENT.CONTROL.REQUEST
| typeof EVENT.CONTROL.GIVE
| typeof EVENT.CONTROL.CLIPBOARD
| typeof EVENT.CONTROL.KEYBOARD
export type ScreenEvents = typeof EVENT.SCREEN.CONFIGURATIONS | typeof EVENT.SCREEN.RESOLUTION | typeof EVENT.SCREEN.SET
export type BroadcastEvents =
| typeof EVENT.BROADCAST.STATUS
| typeof EVENT.BROADCAST.CREATE
| typeof EVENT.BROADCAST.DESTROY
export type AdminEvents =
| typeof EVENT.ADMIN.BAN
| typeof EVENT.ADMIN.KICK
| typeof EVENT.ADMIN.LOCK
| typeof EVENT.ADMIN.UNLOCK
| typeof EVENT.ADMIN.MUTE
| typeof EVENT.ADMIN.UNMUTE
| typeof EVENT.ADMIN.CONTROL
| typeof EVENT.ADMIN.RELEASE
| typeof EVENT.ADMIN.GIVE

183
src/types/messages.ts Normal file
View File

@ -0,0 +1,183 @@
import {
EVENT,
WebSocketEvents,
SystemEvents,
SignalEvents,
MemberEvents,
ControlEvents,
ScreenEvents,
BroadcastEvents,
AdminEvents,
} from './events'
import {
Member,
ScreenConfigurations,
ScreenResolution
} from './structs'
export type WebSocketMessages =
| WebSocketMessage
| SignalProvideMessage
| SignalAnswerMessage
| MemberListMessage
| MemberConnectMessage
| MemberDisconnectMessage
| ControlMessage
| ScreenResolutionMessage
| ScreenConfigurationsMessage
export type WebSocketPayloads =
| SignalProvidePayload
| SignalAnswerPayload
| MemberListPayload
| Member
| ControlPayload
| ControlClipboardPayload
| ControlKeyboardPayload
| ScreenResolutionPayload
| ScreenConfigurationsPayload
| AdminPayload
| BroadcastStatusPayload
| BroadcastCreatePayload
export interface WebSocketMessage {
event: WebSocketEvents | string
}
/*
SYSTEM MESSAGES/PAYLOADS
*/
// system/disconnect
export interface DisconnectMessage extends WebSocketMessage, DisconnectPayload {
event: typeof EVENT.SYSTEM.DISCONNECT
}
export interface DisconnectPayload {
message: string
}
/*
SIGNAL MESSAGES/PAYLOADS
*/
// signal/provide
export interface SignalProvideMessage extends WebSocketMessage, SignalProvidePayload {
event: typeof EVENT.SIGNAL.PROVIDE
}
export interface SignalProvidePayload {
id: string
lite: boolean
ice: string[]
sdp: string
}
// signal/answer
export interface SignalAnswerMessage extends WebSocketMessage, SignalAnswerPayload {
event: typeof EVENT.SIGNAL.ANSWER
}
export interface SignalAnswerPayload {
sdp: string
displayname: string
}
/*
MEMBER MESSAGES/PAYLOADS
*/
// member/list
export interface MemberListMessage extends WebSocketMessage, MemberListPayload {
event: typeof EVENT.MEMBER.LIST
}
export interface MemberListPayload {
members: Member[]
}
// member/connected
export interface MemberConnectMessage extends WebSocketMessage, MemberPayload {
event: typeof EVENT.MEMBER.CONNECTED
}
export type MemberPayload = Member
// member/disconnected
export interface MemberDisconnectMessage extends WebSocketMessage, MemberPayload {
event: typeof EVENT.MEMBER.DISCONNECTED
}
export interface MemberDisconnectPayload {
id: string
}
/*
CONTROL MESSAGES/PAYLOADS
*/
// control/locked & control/release & control/request
export interface ControlMessage extends WebSocketMessage, ControlPayload {
event: ControlEvents
}
export interface ControlPayload {
id: string
}
export interface ControlTargetPayload {
id: string
target: string
}
export interface ControlClipboardPayload {
text: string
}
export interface ControlKeyboardPayload {
layout?: string
capsLock?: boolean
numLock?: boolean
scrollLock?: boolean
}
/*
SCREEN PAYLOADS
*/
export interface ScreenResolutionMessage extends WebSocketMessage, ScreenResolutionPayload {
event: ScreenEvents
}
export interface ScreenResolutionPayload extends ScreenResolution {
id?: string
}
export interface ScreenConfigurationsMessage extends WebSocketMessage, ScreenConfigurationsPayload {
event: ScreenEvents
}
export interface ScreenConfigurationsPayload {
configurations: ScreenConfigurations
}
/*
BROADCAST PAYLOADS
*/
export interface BroadcastCreatePayload {
url: string
}
export interface BroadcastStatusPayload {
url: string
isActive: boolean
}
/*
ADMIN PAYLOADS
*/
export interface AdminMessage extends WebSocketMessage, AdminPayload {
event: AdminEvents
}
export interface AdminPayload {
id: string
}
export interface AdminTargetMessage extends WebSocketMessage, AdminTargetPayload {
event: AdminEvents
}
export interface AdminTargetPayload {
id: string
target?: string
}

26
src/types/structs.ts Normal file
View File

@ -0,0 +1,26 @@
export interface Member {
id: string
displayname: string
admin: boolean
muted: boolean
connected?: boolean
ignored?: boolean
}
export interface ScreenConfigurations {
[index: string]: ScreenConfiguration
}
export interface ScreenConfiguration {
width: number
height: number
rates: {
[index: string]: number
}
}
export interface ScreenResolution {
width: number
height: number
rate: number
}