websocket sessions now get a UID + graceful close/cleanup, server graceful shutdown
This commit is contained in:
parent
e9d3ab17ca
commit
f049888aa7
2 changed files with 61 additions and 7 deletions
|
@ -1,3 +1,5 @@
|
||||||
|
import crypto from 'crypto'
|
||||||
|
|
||||||
const async_build_js_script = async function (path_js_entry_script, build_options) {
|
const async_build_js_script = async function (path_js_entry_script, build_options) {
|
||||||
const result = await Bun.build({
|
const result = await Bun.build({
|
||||||
entrypoints: [ path_js_entry_script ],
|
entrypoints: [ path_js_entry_script ],
|
||||||
|
@ -25,7 +27,7 @@ const get_siteroot_html = function ({ page_title }) {return `
|
||||||
</html>
|
</html>
|
||||||
`.trim()}
|
`.trim()}
|
||||||
|
|
||||||
const start_server = function ({ config, jsbuild_app_frontend }) {
|
const start_server = function ({ context_meta, config, jsbuild_app_frontend }) {
|
||||||
const server = Bun.serve({
|
const server = Bun.serve({
|
||||||
hostname: config.host || '127.0.0.1',
|
hostname: config.host || '127.0.0.1',
|
||||||
port : config.port || 8800,
|
port : config.port || 8800,
|
||||||
|
@ -50,8 +52,13 @@ const start_server = function ({ config, jsbuild_app_frontend }) {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
else if (url.pathname === '/ws') {
|
else if (url.pathname === '/ws') {
|
||||||
if (server.upgrade(req)) {
|
const uid = crypto.randomUUID()
|
||||||
// do not return a Response if upgrade fails
|
if (server.upgrade(req, {
|
||||||
|
data: {
|
||||||
|
uid,
|
||||||
|
},
|
||||||
|
})) {
|
||||||
|
// do not return a Response if upgrade succeeds
|
||||||
resp = undefined
|
resp = undefined
|
||||||
}
|
}
|
||||||
resp = new Response('Upgrade failed', { status: 500 })
|
resp = new Response('Upgrade failed', { status: 500 })
|
||||||
|
@ -62,20 +69,67 @@ const start_server = function ({ config, jsbuild_app_frontend }) {
|
||||||
return resp
|
return resp
|
||||||
},
|
},
|
||||||
websocket: {
|
websocket: {
|
||||||
|
open: function (ws) {
|
||||||
|
const map_obj = {
|
||||||
|
ws,
|
||||||
|
closed_by_server: false,
|
||||||
|
}
|
||||||
|
context_meta.ws_map.set(ws.data.uid, map_obj)
|
||||||
|
return
|
||||||
|
},
|
||||||
|
close: function (ws, code, message) {
|
||||||
|
const map_obj = context_meta.ws_map.get(ws.data.uid)
|
||||||
|
if (map_obj === undefined) {
|
||||||
|
console.warn(['Unexpected: ws_map missing uid', ws.data.uid])
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (map_obj.closed_by_server === true) {
|
||||||
|
console.info(['ws closed by server', ws.data.uid])
|
||||||
|
// cleanup will happen in outer context
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
console.info(['ws closed by client', ws.data.uid, { code, message }])
|
||||||
|
// cleanup from this context
|
||||||
|
context_meta.ws_map.delete(ws.data.uid)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
},
|
||||||
message: function (ws, message) {},
|
message: function (ws, message) {},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
return server
|
return server
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const close_active_ws_sessions = function ({ context_meta }) {
|
||||||
|
const keys_to_delete = []
|
||||||
|
for (const [ uid, map_obj ] of context_meta.ws_map) {
|
||||||
|
const code = 1001
|
||||||
|
const reason = 'Going Away'
|
||||||
|
map_obj.closed_by_server = true
|
||||||
|
map_obj.ws.close(code, reason)
|
||||||
|
keys_to_delete.push(uid)
|
||||||
|
}
|
||||||
|
for (let key of keys_to_delete) {
|
||||||
|
context_meta.ws_map.delete(key)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
const async_run = async function ({
|
const async_run = async function ({
|
||||||
config,
|
config,
|
||||||
jsbuild_app_frontend,
|
jsbuild_app_frontend,
|
||||||
}) {
|
}) {
|
||||||
const server = start_server({ config, jsbuild_app_frontend })
|
const context_meta = {
|
||||||
|
ws_map: new Map(),
|
||||||
|
}
|
||||||
|
const server = start_server({ context_meta, config, jsbuild_app_frontend })
|
||||||
console.info(server)
|
console.info(server)
|
||||||
process.on('SIGINT', () => {
|
process.on('SIGINT', async () => {
|
||||||
console.log('SIGINT intercepted')
|
console.log('SIGINT intercepted')
|
||||||
|
close_active_ws_sessions({ context_meta })
|
||||||
|
// NOTE: wait for a second for teardown to fully complete
|
||||||
|
await Bun.sleep(2000)
|
||||||
process.exit()
|
process.exit()
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
|
|
|
@ -42,9 +42,9 @@ class FramerockUtils {
|
||||||
on_open && on_open()
|
on_open && on_open()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const func_on_close = () => {
|
const func_on_close = (event) => {
|
||||||
console.info('WS CLOSE')
|
console.info('WS CLOSE')
|
||||||
on_close && on_close()
|
on_close && on_close(event)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const func_on_message = (e) => {
|
const func_on_message = (e) => {
|
||||||
|
|
Loading…
Add table
Reference in a new issue