Skip to content

Commit

Permalink
refactor: initial connection attempt via websocket
Browse files Browse the repository at this point in the history
Signed-off-by: Pedro Lamas <[email protected]>
  • Loading branch information
pedrolamas committed Jun 21, 2023
1 parent aa9e79c commit 5ea5ce2
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 7 deletions.
5 changes: 4 additions & 1 deletion src/components/common/AddInstanceDialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ import StateMixin from '@/mixins/state'
import { Debounce } from 'vue-debounce-decorator'
import { consola } from 'consola'
import { httpClientActions } from '@/api/httpClientActions'
import webSocketWrapper from '@/util/web-socket-wrapper'
@Component({})
export default class AddInstanceDialog extends Mixins(StateMixin) {
Expand Down Expand Up @@ -193,7 +194,9 @@ export default class AddInstanceDialog extends Mixins(StateMixin) {
this.controller = new AbortController()
const { signal } = this.controller
await fetch(url + 'server/info', { signal, mode: 'no-cors', cache: 'no-cache' })
const apiEndpoints = this.$filters.getApiUrls(url.toString())
await webSocketWrapper(apiEndpoints.socketUrl, signal)
.then(() => {
// likely a cors issue
this.error = this.$t('app.endpoint.error.cors_error')
Expand Down
11 changes: 5 additions & 6 deletions src/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import axios from 'axios'
import router from './router'
import { httpClientActions } from '@/api/httpClientActions'
import sanitizeEndpoint from '@/util/sanitize-endpoint'
import webSocketWrapper from '@/util/web-socket-wrapper'

// Load API configuration
/**
Expand Down Expand Up @@ -75,15 +76,13 @@ const getApiConfig = async (hostConfig: HostConfig): Promise<ApiConfig | Instanc
// If none are, we'll force the instance add dialog.
// A 401 would indicate a good ping, since it's potentially an authenticated,
// endpoint but working instance.
const results = await Promise.all(
endpoints.map(async endpoint => {
return httpClientActions.get(`${endpoint}/server/info?date=${Date.now()}`, { timeout: 1000 })
.then(() => true)
.catch((error) => error.response?.status === 401)
const i = await Promise.race(
endpoints.map(async (endpoint, index) => {
const apiEndpoints = Vue.$filters.getApiUrls(endpoint)
return await webSocketWrapper(apiEndpoints.socketUrl) ? index : -1
})
)

const i = results.findIndex(endpoint => endpoint)
return (i > -1)
? Vue.$filters.getApiUrls(endpoints[i])
: { apiUrl: '', socketUrl: '' }
Expand Down
41 changes: 41 additions & 0 deletions src/util/web-socket-wrapper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { consola } from 'consola'

const webSocketWrapper = (url: string, signal?: AbortSignal) => {
return new Promise<boolean>((resolve) => {
consola.debug(`[webSocketWrapper] open ${url}`)

const connection = new WebSocket(url)

const dispose = () => {
signal?.removeEventListener('abort', abortHandler)

connection.close()
}

const abortHandler = () => dispose()

signal?.addEventListener('abort', abortHandler)

connection.onopen = () => {
consola.debug(`[webSocketWrapper] ${url} open`)

resolve(true)

dispose()
}

connection.onerror = () => {
consola.debug(`[webSocketWrapper] ${url} error`)

resolve(false)

dispose()
}

connection.onclose = () => {
consola.debug(`[webSocketWrapper] ${url} close`)
}
})
}

export default webSocketWrapper

0 comments on commit 5ea5ce2

Please sign in to comment.