mirror of
https://github.com/YunoHost/yunohost-admin.git
synced 2024-09-03 20:06:15 +02:00
sse: properly handle sse opening/closing
This commit is contained in:
parent
0b1030a2fb
commit
2d78749c1d
4 changed files with 39 additions and 41 deletions
|
@ -81,7 +81,6 @@
|
|||
|
||||
<script>
|
||||
import { mapGetters } from 'vuex'
|
||||
import { connectSSE } from '@/api/handlers'
|
||||
import { HistoryConsole, ViewLockOverlay } from '@/views/_partials'
|
||||
|
||||
export default {
|
||||
|
@ -118,7 +117,7 @@ export default {
|
|||
// state will be automaticly reseted and user will be prompt with the login view.
|
||||
if (this.connected) {
|
||||
this.$store.dispatch('GET_YUNOHOST_INFOS')
|
||||
connectSSE()
|
||||
this.$store.dispatch('SSE_CONNECT')
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
*/
|
||||
|
||||
import store from '@/store'
|
||||
import { openWebSocket, getResponseData, handleError } from './handlers'
|
||||
import { getResponseData, handleError } from './handlers'
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
@ -24,40 +24,6 @@ export async function getResponseData (response) {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Opens a WebSocket connection to the server in case it sends messages.
|
||||
* Currently, the connection is closed by the server right after an API call so
|
||||
* we have to open it for every calls.
|
||||
* Messages are dispatch to the store so it can handle them.
|
||||
*
|
||||
* @param {Object} request - Request info data.
|
||||
* @return {Promise<Event>} Promise that resolve on websocket 'open' or 'error' event.
|
||||
*/
|
||||
export function openWebSocket (request) {
|
||||
return new Promise(resolve => {
|
||||
const ws = new WebSocket(`wss://${store.getters.host}/yunohost/api/messages`)
|
||||
ws.onmessage = ({ data }) => {
|
||||
store.dispatch('DISPATCH_MESSAGE', { request, messages: JSON.parse(data) })
|
||||
}
|
||||
// ws.onclose = (e) => {}
|
||||
ws.onopen = resolve
|
||||
// Resolve also on error so the actual fetch may be called.
|
||||
ws.onerror = resolve
|
||||
})
|
||||
}
|
||||
|
||||
export function connectSSE () {
|
||||
const host = store.getters.host.split(':')[0]
|
||||
const evtSource = new EventSource(`https://${host}/yunohost/api/sse`)
|
||||
|
||||
evtSource.onmessage = (event) => {
|
||||
store.dispatch('ON_SSE_MESSAGE', JSON.parse(atob(event.data)))
|
||||
}
|
||||
|
||||
// FIXME handle 'onerror' hook
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handler for API errors.
|
||||
*
|
||||
|
|
|
@ -2,13 +2,13 @@ import Vue from 'vue'
|
|||
import router from '@/router'
|
||||
import i18n from '@/i18n'
|
||||
import api from '@/api'
|
||||
import { connectSSE } from '@/api/handlers'
|
||||
import { timeout, isEmptyValue, isObjectLiteral } from '@/helpers/commons'
|
||||
|
||||
export default {
|
||||
state: {
|
||||
host: window.location.host, // String
|
||||
connected: localStorage.getItem('connected') === 'true', // Boolean
|
||||
sse: null, // EventSource
|
||||
yunohost: null, // Object { version, repo }
|
||||
waiting: false, // Boolean
|
||||
reconnecting: null, // null|Object { attemps, delay, initialDelay }
|
||||
|
@ -28,6 +28,17 @@ export default {
|
|||
state.connected = boolean
|
||||
},
|
||||
|
||||
'SET_SSE_SOURCE' (state, sse) {
|
||||
state.sse = sse
|
||||
},
|
||||
|
||||
'CLOSE_SSE_SOURCE' (state) {
|
||||
if (state.sse) {
|
||||
state.sse.close()
|
||||
state.sse = null
|
||||
}
|
||||
},
|
||||
|
||||
'SET_YUNOHOST_INFOS' (state, yunohost) {
|
||||
state.yunohost = yunohost
|
||||
},
|
||||
|
@ -123,13 +134,30 @@ export default {
|
|||
|
||||
'CONNECT' ({ commit, dispatch }) {
|
||||
commit('SET_CONNECTED', true)
|
||||
connectSSE()
|
||||
dispatch('GET_YUNOHOST_INFOS')
|
||||
dispatch('SSE_CONNECT')
|
||||
},
|
||||
|
||||
'SSE_CONNECT' ({ commit, dispatch }) {
|
||||
const sse = new EventSource(`/yunohost/api/sse`, { withCredentials: true })
|
||||
|
||||
sse.onopen = () => {
|
||||
commit('SET_SSE_SOURCE', sse)
|
||||
console.log('connected')
|
||||
};
|
||||
|
||||
sse.onmessage = (event) => {
|
||||
dispatch('ON_SSE_MESSAGE', JSON.parse(atob(event.data)))
|
||||
}
|
||||
|
||||
// sse.onerror = (event) => {
|
||||
// }
|
||||
},
|
||||
|
||||
'RESET_CONNECTED' ({ commit }) {
|
||||
commit('SET_CONNECTED', false)
|
||||
commit('SET_YUNOHOST_INFOS', null)
|
||||
commit('CLOSE_SSE_SOURCE')
|
||||
},
|
||||
|
||||
'DISCONNECT' ({ dispatch }, route = router.currentRoute) {
|
||||
|
@ -249,7 +277,13 @@ export default {
|
|||
},
|
||||
|
||||
async 'ON_SSE_MESSAGE' ({ state, commit, dispatch }, data) {
|
||||
let action = state.history.findLast((action) => action.operationId === data.operation_id)
|
||||
let action
|
||||
if (data.type === 'start') {
|
||||
action = state.requests.findLast((request) => request.status === 'pending')
|
||||
} else {
|
||||
action = state.history.findLast((action) => action.operationId === data.operation_id)
|
||||
}
|
||||
|
||||
if (!action) {
|
||||
action = await dispatch('START_EXTERNAL_ACTION', { operationId: data.operation_id, timestamp: data.timestamp })
|
||||
}
|
||||
|
@ -288,7 +322,6 @@ export default {
|
|||
}
|
||||
commit('ADD_TEMP_MESSAGE', { request: action, message, type })
|
||||
}
|
||||
action.messages.push(message)
|
||||
}
|
||||
},
|
||||
|
||||
|
|
Loading…
Reference in a new issue