wo-base-websocket-server/index.js

83 lines
2.7 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

const ws = require('ws')
const webtoken = require('base.webtoken')
const my = {
wssServer: undefined,
socketPool: {},
listeners: {},
}
module.exports = {
initSocket: (webServer) => {
my.wssServer = new ws.Server({ server: webServer })
console.info('App Socket Server attached to web server.')
my.wssServer.on('connection', (socket, req) => {
console.info(`A socket from App Client is connected from ${req.connection.remoteAddress}:${req.connection.remotePort}.`)
// socket.isAlive = true
// socket.on('pong', function() { console.log('👈 ASS: on Pong'); this.isAlive = true })
socket.on('message', (data) => {
// 在这里统一分发消息
console.log('App Socket Client message: ', data)
let dataObj
try {
dataObj = JSON.parse(data)
} catch (exception) {
console.log(new Date().toJSON(), 'Unable to parse socket message: ', data)
return
}
if (dataObj.skevent === 'SOCKET_OWNER') {
dataObj._passtokenSource = webtoken.verifyToken(dataObj._passtoken, wo.envi.tokenKey) // todo: 为防止前端欺骗应当用和login里类似的方法来检查来检查
my.socketPool[dataObj._passtokenSource.uuid] = socket
console.log('收到Login 成功的消息绑定socket', Object.keys(my.socketPool))
// this.sendToOne({skevent:'ws/Exchange/paintedWolf', info:'launch to mars'}, dataObj._passtokenSource.uuid)
}
const listeners = my.listeners[dataObj.skevent] || []
for (const listener of listeners) {
listener(dataObj)
}
})
})
return this
},
removeUserSocket: (uuid) => {
delete my.socketPool[uuid]
},
addListener: (skevent, listener) => {
if (Array.isArray(my.listeners[skevent]) && typeof listener === 'function') {
my.listeners[skevent].push(listener)
} else {
my.listeners[skevent] = [listener]
}
return this
},
sendToAll: (dataObj) => {
my.wssServer.clients.forEach((socket) => {
if (socket.readyState === socket.OPEN) {
socket.send(typeof dataObj !== 'string' ? JSON.stringify(dataObj) : dataObj)
} else {
delete my.socketPool[socket.uuid]
}
})
},
sendToOne: (dataObj, uuid) => {
const socket = my.socketPool[uuid]
if (socket && socket.readyState === socket.OPEN) {
socket.send(typeof dataObj !== 'string' ? JSON.stringify(dataObj) : dataObj)
} else {
delete my.socketPool[uuid]
}
},
}
// todo: 前端断线重连时,并不会再次 login_success。也许在前端的initSocket时应当把_passtoken送过来而后台则对_passtoken做验证后再加socketPool。