From 115e1be73e4db656d4446ace41977f21f1ef9ba8 Mon Sep 17 00:00:00 2001 From: Luk Lu Date: Sun, 20 Jun 2021 09:07:40 +0800 Subject: [PATCH] init this repo --- .gitignore | 17 +++++++++++ .prettierrc.js | 16 ++++++++++ README.md | 3 +- index.js | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++ package.json | 14 +++++++++ 5 files changed, 130 insertions(+), 2 deletions(-) create mode 100644 .gitignore create mode 100644 .prettierrc.js create mode 100644 index.js create mode 100644 package.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3d3c395 --- /dev/null +++ b/.gitignore @@ -0,0 +1,17 @@ +.DS_Store +node_modules/ +npm-debug.log* +yarn-debug.log* +yarn-error.log* +/test/unit/coverage/ +/test/e2e/reports/ +selenium-debug.log + +# Editor directories and files +.idea +.vscode +*.suo +*.ntvs* +*.njsproj +*.sln +/package-lock.json diff --git a/.prettierrc.js b/.prettierrc.js new file mode 100644 index 0000000..e001ecd --- /dev/null +++ b/.prettierrc.js @@ -0,0 +1,16 @@ +/* +对 VSCode Prettier 有效;建议一直要有本配置文件,否则不同版本的 Prettier 的默认配置会不同,例如 TrailingComma +对 VSCode Prettier Standard 无效,似乎是集成了不能修改的配置。 +*/ +module.exports = { + printWidth: 160, // default 80 + tabWidth: 2, // default 2 + useTabs: false, + semi: false, // default true + singleQuote: true, // default false + trailingComma: 'es5', // none (default in v 1.*), es5 (default in v2.0.0), all + bracketSpacing: true, // default true + jsxBracketSameLine: false, // default false + arrowParens: 'always', // avoid (default in v1.9.0), always (default since v2.0.0) + quoteProps: 'as-needed', // as-needed (default), consistent, preserve +} diff --git a/README.md b/README.md index 0fc5237..8a06509 100644 --- a/README.md +++ b/README.md @@ -1,2 +1 @@ -# sol.webServerSocket - +# sol.webServerSocket | web服务端套接口 \ No newline at end of file diff --git a/index.js b/index.js new file mode 100644 index 0000000..1708858 --- /dev/null +++ b/index.js @@ -0,0 +1,82 @@ +const ws = require('ws') +const webtoken = require('sol.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。 diff --git a/package.json b/package.json new file mode 100644 index 0000000..5ae300d --- /dev/null +++ b/package.json @@ -0,0 +1,14 @@ +{ + "name": "sol.webServerSocket", + "version": "0.1.0", + "private": true, + "dependencies": { + "sol.webtoken": "git+https://git.faronear.org/npm/sol.webtoken", + "ws": "^7.2.1" + }, + "devDependencies": {}, + "scripts": { + "setup": "npm install" + }, + "author": "" +}