const http = require('http') const sio = require('socket.io') const { createHttpTerminator } = require('http-terminator') const modules = require('../modules') const { authCode, authConnect } = require('./auth') const { getAddress, getServerId, generateCode, getClientKeyInfo } = require('./utils') const syncList = require('./syncList') let status = { status: false, message: '', address: [], code: '', devices: [], } const handleConnection = (io, socket) => { console.log('connection') // console.log(socket.handshake.query) for (const module of Object.values(modules)) { module.registerListHandler(io, socket) } } const authConnection = (req, callback) => { // console.log(req.headers) // // console.log(req.auth) // console.log(req._query.authCode) authConnect(req).then(() => { callback(null, true) }).catch(err => { callback(err, false) }) } let httpTerminator = null let io = null const handleStartServer = (port = 9527) => new Promise((resolve, reject) => { const httpServer = http.createServer((req, res) => { // console.log(req.url) let code let msg switch (req.url) { case '/hello': code = 200 msg = 'Hello~::^-^::' break case '/id': code = 200 msg = 'OjppZDo6' + getServerId() break case '/ah': authCode(req, res, status.code) break default: code = 401 msg = 'Forbidden' break } if (!code) return res.writeHead(code) res.end(msg) }) httpTerminator = createHttpTerminator({ server: httpServer, }) io = sio(httpServer, { path: '/sync', serveClient: false, connectTimeout: 10000, pingTimeout: 30000, maxHttpBufferSize: 3e6, allowRequest: authConnection, transports: ['websocket'], }) io.on('connection', async socket => { socket.on('disconnect', reason => { console.log('disconnect', reason) status.devices.splice(status.devices.findIndex(k => k.clientId == keyInfo.clientId), 1) global.lx_event.sync.status(status) }) const keyInfo = getClientKeyInfo(socket.handshake.query.i) // socket.lx_keyInfo = keyInfo socket.data.keyInfo = keyInfo try { await syncList(io, socket) } catch (err) { console.log(err) return } status.devices.push(keyInfo) handleConnection(io, socket, keyInfo) global.lx_event.sync.status(status) }) httpServer.on('error', error => { console.log(error) reject(error) }) httpServer.on('listening', () => { const addr = httpServer.address() const bind = typeof addr === 'string' ? 'pipe ' + addr : 'port ' + addr.port console.info(`Listening on ${bind}`) resolve() }) httpServer.listen(port) }) const handleStopServer = async() => { if (!httpTerminator) return await io.close() await httpTerminator.terminate().catch(() => {}) io = null httpTerminator = null } exports.stopServer = async() => { if (!status.status) { status.status = false status.message = '' status.address = [] status.code = '' global.lx_event.sync.status(status) return } console.log('stoping sync server...') return handleStopServer().then(() => { console.log('sync server stoped') status.status = false status.message = '' status.address = [] status.code = '' }).catch(err => { console.log(err) status.message = err.message }).finally(() => { global.lx_event.sync.status(status) }) } exports.startServer = async port => { if (status.status) await handleStopServer() console.log('starting sync server...') return handleStartServer(port).then(() => { console.log('sync server started') status.status = true status.message = '' status.address = getAddress() status.code = generateCode() }).catch(err => { console.log(err) status.status = false status.message = err.message status.address = [] status.code = '' }).finally(() => { global.lx_event.sync.status(status) }) } exports.getStatus = () => status exports.generateCode = async() => { status.code = generateCode() global.lx_event.sync.status(status) return status.code }