rsnext/packages/next/client/dev/error-overlay/websocket.ts
Genet Schneider e3135ccde6
Support assetPrefix specific protocol (#31213)
Co-authored-by: JJ Kasper <jj@jjsweb.site>
2021-11-09 15:26:55 -06:00

81 lines
1.8 KiB
TypeScript

let source: WebSocket
const eventCallbacks: ((event: any) => void)[] = []
let lastActivity = Date.now()
function getSocketProtocol(assetPrefix: string): string {
let protocol = location.protocol
try {
// assetPrefix is a url
protocol = new URL(assetPrefix).protocol
} catch (_) {}
return protocol === 'http:' ? 'ws' : 'wss'
}
export function addMessageListener(cb: (event: any) => void) {
eventCallbacks.push(cb)
}
export function sendMessage(data: any) {
if (!source || source.readyState !== source.OPEN) return
return source.send(data)
}
export function connectHMR(options: {
path: string
assetPrefix: string
timeout: number
log?: boolean
}) {
if (!options.timeout) {
options.timeout = 5 * 1000
}
init()
let timer = setInterval(function () {
if (Date.now() - lastActivity > options.timeout) {
handleDisconnect()
}
}, options.timeout / 2)
function init() {
if (source) source.close()
const { hostname, port } = location
const protocol = getSocketProtocol(options.assetPrefix || '')
const assetPrefix = options.assetPrefix.replace(/^\/+/, '')
let url = `${protocol}://${hostname}:${port}${
assetPrefix ? `/${assetPrefix}` : ''
}`
if (assetPrefix.startsWith('http')) {
url = `${protocol}://${assetPrefix.split('://')[1]}`
}
source = new window.WebSocket(`${url}${options.path}`)
source.onopen = handleOnline
source.onerror = handleDisconnect
source.onmessage = handleMessage
}
function handleOnline() {
if (options.log) console.log('[HMR] connected')
lastActivity = Date.now()
}
function handleMessage(event: any) {
lastActivity = Date.now()
eventCallbacks.forEach((cb) => {
cb(event)
})
}
function handleDisconnect() {
clearInterval(timer)
source.close()
setTimeout(init, options.timeout)
}
}