You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
75 lines
2.6 KiB
75 lines
2.6 KiB
// Firefox does randomized exponential backoff for failed websocket requests |
|
// This means we can't have [1. long downtime] and [2. fast reconnect] at the sime time |
|
// |
|
// We abuse the fact that HTTP requests are NOT backoffed, and use those to monitor |
|
// the server. When we see that the server is up - we attempt an actual websocket connection |
|
// |
|
// Details best described here: https://github.com/kee-org/KeeFox/issues/189 |
|
|
|
async function ws_connect(state, context, first_connect = false) { |
|
const session_id = localStorage.getItem('sessionId') || '0'; |
|
const desk_id = state.desk_id; |
|
|
|
try { |
|
const resp = await fetch(config.ping_url); |
|
|
|
if (resp.ok) { |
|
const text = await resp.text(); |
|
|
|
if (text === 'pong') { |
|
ws = new WebSocket(`${config.ws_url}?deskId=${desk_id}&sessionId=${session_id}`); |
|
|
|
ws.addEventListener('open', () => on_open(state)); |
|
ws.addEventListener('message', (e) => on_message(state, context, e)); |
|
ws.addEventListener('error', () => on_error(state, context)); |
|
ws.addEventListener('close', () => on_close(state, context)); |
|
|
|
return; |
|
} |
|
} |
|
} catch (e) { |
|
console.log('Could not ping the server:', e); |
|
} |
|
|
|
state.timers.offline_toast = setTimeout(() => ws_connect(state, context, first_connect), config.ws_reconnect_timeout); |
|
} |
|
|
|
function on_open(state) { |
|
clearTimeout(state.timers.offline_toast); |
|
ui_online(); |
|
if (config.debug_print) console.debug('open') |
|
} |
|
|
|
async function on_message(state, context, event) { |
|
const data = event.data; |
|
let message_data = null; |
|
|
|
if ('arrayBuffer' in data) { |
|
message_data = await data.arrayBuffer(); |
|
const view = new DataView(message_data); |
|
const d = deserializer_create(message_data, view); |
|
await handle_message(state, context, d); |
|
} else { |
|
/* For all my Safari < 14 bros out there */ |
|
const reader = new FileReader(); |
|
reader.onload = async (e) => { |
|
message_data = e.target.result; |
|
const view = new DataView(message_data); |
|
const d = deserializer_create(message_data, view); |
|
await handle_message(state, context, d); |
|
}; |
|
|
|
reader.readAsArrayBuffer(data); |
|
} |
|
} |
|
|
|
function on_close(state, context) { |
|
state.timers.offline_toast = setTimeout(() => ui_offline(), config.initial_offline_timeout); |
|
ws = null; |
|
if (config.debug_print) console.debug('close'); |
|
ws_connect(state, context, false); |
|
} |
|
|
|
function on_error(state, context) { |
|
ws.close(state, context); |
|
}
|
|
|