pp / lib /server /Client.js
xwwww's picture
Upload 253 files
6d0ad0e verified
import WebSocket from 'ws'
import { logger, puppeteer } from '#karin'
import VueCache from './VueFileCache.js'
import { Config } from '#karin'
export const store = new Map()
export default class WebSocketClient {
constructor (url, headerId) {
this.url = url
this.headerId = headerId
this.ws = null
this.statr = false
this.vueCache = VueCache
}
/** 创建 WebSocket 连接 */
createWebSocket () {
this.ws = new WebSocket(this.url, {
headers: {
'renderer-id': this.headerId,
'renderer-type': 'image'
}
})
this.ws.on('open', () => {
this.statr = true
logger.mark('[反向WS][连接成功]', this.url)
/** 每5秒发一次心跳 中断就重连 */
this.timer = setInterval(() => {
try {
this.ws.send(JSON.stringify({ action: 'heartbeat', data: { status: 'ok' } }))
} catch (e) {
logger.error('[反向WS]心跳异常:', this.url)
logger.error(e)
/** 关闭连接 */
this.ws.close()
clearInterval(this.timer)
}
}, 5000)
})
/** 反向ws暂时只考虑渲染本地文件或http */
this.ws.on('message', async message => {
message = JSON.parse(message)
logger.debug(`[反向WS][渲染] URL: ${this.url} html:${message.data.file}`)
const action = 'renderRes'
const { echo, data } = message
let res
if (data.vue && Config.Config.server.http) {
const cacheId = this.vueCache.addCache(data.file, data.name, data.props)
res = await puppeteer.screenshot({...data, ...{file: `http://localhost:${Config.Config.http.port}/vue/${data.vueTemplate || 'default'}/?id=${cacheId}`}})
this.vueCache.deleteCache(cacheId)
} else {
res = await puppeteer.screenshot(data)
}
res.echo = echo
res.action = action
return this.ws.send(JSON.stringify(res))
})
/** 连接断开 */
this.ws.on('close', () => {
this.statr = false
logger.error('[反向WS][连接错误]:', this.url)
try { clearInterval(this.timer) } catch { }
this.reconnect()
})
/** 连接错误 */
this.ws.on('error', error => {
logger.debug(error)
})
}
/** 重连函数 */
reconnect () {
setTimeout(this.createWebSocket.bind(this), 5000)
}
}