chore(websocket): add function to send and wait for response (#2004)

This commit is contained in:
Stefan Dej
2024-09-16 00:45:12 +02:00
committed by GitHub
parent 3b4de5fc25
commit de697da87b
2 changed files with 62 additions and 29 deletions

View File

@@ -30,6 +30,13 @@ export class WebSocketClient {
handleMessage(data: any) { handleMessage(data: any) {
const wait = this.getWaitById(data.id) const wait = this.getWaitById(data.id)
// reject promise if it exists
if ('error' in data && wait?.reject) {
wait.reject(data.error)
this.removeWaitById(wait.id)
return
}
// report error messages // report error messages
if (data.error?.message) { if (data.error?.message) {
// only report errors, if not disconnected and no init component // only report errors, if not disconnected and no init component
@@ -37,12 +44,7 @@ export class WebSocketClient {
window.console.error(`Response Error: ${data.error.message} (${wait?.action ?? 'no action'})`) window.console.error(`Response Error: ${data.error.message} (${wait?.action ?? 'no action'})`)
} }
if (data.error.message === 'Unauthorized' && wait?.action === 'server/setConnectionId') { if (wait) {
this.close()
this.store?.dispatch('socket/setConnectionFailed', data.error.message)
}
if (wait?.id) {
const modulename = wait.action?.split('/')[1] ?? null const modulename = wait.action?.split('/')[1] ?? null
if ( if (
@@ -69,8 +71,11 @@ export class WebSocketClient {
return return
} }
// resolve promise if it exists
if (wait?.resolve) wait.resolve(data.result ?? {})
// pass result to action // pass result to action
if (wait?.action) { if (wait.action) {
let result = data.result let result = data.result
if (result === 'ok') result = { result: result } if (result === 'ok') result = { result: result }
if (typeof result === 'string') result = { result: result } if (typeof result === 'string') result = { result: result }
@@ -164,7 +169,7 @@ export class WebSocketClient {
if (options.loading) this.store?.dispatch('socket/addLoading', { name: options.loading }) if (options.loading) this.store?.dispatch('socket/addLoading', { name: options.loading })
this.instance.send( this.instance?.send(
JSON.stringify({ JSON.stringify({
jsonrpc: '2.0', jsonrpc: '2.0',
method, method,
@@ -174,6 +179,34 @@ export class WebSocketClient {
) )
} }
async emitAndWait(method: string, params: Params, options: emitOptions = {}): Promise<any> {
return new Promise((resolve, reject) => {
if (this.instance?.readyState !== WebSocket.OPEN) reject()
const id = this.messageId++
this.waits.push({
id: id,
params: params,
action: options.action ?? null,
actionPayload: options.actionPayload ?? {},
loading: options.loading ?? null,
resolve,
reject,
})
if (options.loading) this.store?.dispatch('socket/addLoading', { name: options.loading })
this.instance?.send(
JSON.stringify({
jsonrpc: '2.0',
method,
params,
id,
})
)
})
}
emitBatch(messages: BatchMessage[]): void { emitBatch(messages: BatchMessage[]): void {
if (messages.length === 0) return if (messages.length === 0) return
if (this.instance?.readyState !== WebSocket.OPEN) return if (this.instance?.readyState !== WebSocket.OPEN) return
@@ -245,6 +278,8 @@ export interface Wait {
action?: string | null action?: string | null
actionPayload?: any actionPayload?: any
loading?: string | null loading?: string | null
resolve?: (value: any) => void
reject?: (reason: any) => void
} }
interface Params { interface Params {

View File

@@ -16,16 +16,33 @@ export const actions: ActionTree<ServerState, RootState> = {
dispatch('updateManager/reset') dispatch('updateManager/reset')
}, },
async init({ dispatch }) { async init({ commit, dispatch, rootState }) {
window.console.debug('init Server') window.console.debug('init Server')
// identify client
try {
const connection = await Vue.$socket.emitAndWait('server.connection.identify', {
client_name: 'mainsail',
version: rootState.packageVersion,
type: 'web',
url: 'https://github.com/mainsail-crew/mainsail',
})
commit('setConnectionId', connection.connection_id)
} catch (e: any) {
if (e.message === 'Unauthorized') {
this.dispatch('socket/setConnectionFailed', e.message)
}
window.console.error('Error while identifying client: ' + e.message)
return
}
dispatch('socket/addInitModule', 'server/info', { root: true }) dispatch('socket/addInitModule', 'server/info', { root: true })
dispatch('socket/addInitModule', 'server/config', { root: true }) dispatch('socket/addInitModule', 'server/config', { root: true })
dispatch('socket/addInitModule', 'server/systemInfo', { root: true }) dispatch('socket/addInitModule', 'server/systemInfo', { root: true })
dispatch('socket/addInitModule', 'server/procStats', { root: true }) dispatch('socket/addInitModule', 'server/procStats', { root: true })
dispatch('socket/addInitModule', 'server/databaseList', { root: true }) dispatch('socket/addInitModule', 'server/databaseList', { root: true })
dispatch('identify')
Vue.$socket.emit('server.info', {}, { action: 'server/initServerInfo' }) Vue.$socket.emit('server.info', {}, { action: 'server/initServerInfo' })
Vue.$socket.emit('server.config', {}, { action: 'server/initServerConfig' }) Vue.$socket.emit('server.config', {}, { action: 'server/initServerConfig' })
Vue.$socket.emit('machine.system_info', {}, { action: 'server/initSystemInfo' }) Vue.$socket.emit('machine.system_info', {}, { action: 'server/initSystemInfo' })
@@ -35,25 +52,6 @@ export const actions: ActionTree<ServerState, RootState> = {
await dispatch('socket/removeInitModule', 'server', { root: true }) await dispatch('socket/removeInitModule', 'server', { root: true })
}, },
identify({ dispatch, rootState }): void {
dispatch('socket/addInitModule', 'server/identify', { root: true })
Vue.$socket.emit(
'server.connection.identify',
{
client_name: 'mainsail',
version: rootState.packageVersion,
type: 'web',
url: 'https://github.com/mainsail-crew/mainsail',
},
{ action: 'server/setConnectionId' }
)
},
setConnectionId({ commit, dispatch }, payload) {
commit('setConnectionId', payload.connection_id)
dispatch('socket/removeInitModule', 'server/identify', { root: true })
},
checkDatabases({ dispatch, commit }, payload) { checkDatabases({ dispatch, commit }, payload) {
if (payload.namespaces?.includes('mainsail')) { if (payload.namespaces?.includes('mainsail')) {
dispatch('socket/addInitModule', 'gui/init', { root: true }) dispatch('socket/addInitModule', 'gui/init', { root: true })