From 47fc7f79d82b5337f1aa16eb7323b063862d7112 Mon Sep 17 00:00:00 2001 From: zhl Date: Mon, 12 Jul 2021 11:48:58 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=B8=80=E4=B8=AA=E6=A3=80?= =?UTF-8?q?=E6=9F=A5=E6=88=BF=E9=97=B4=E7=8A=B6=E6=80=81=E7=9A=84=E5=AE=9A?= =?UTF-8?q?=E6=97=B6=E4=BB=BB=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 101 +++++++++++++++++++++++++++++++ package.json | 2 + src/api.server.ts | 8 ++- src/common/Debug.ts | 1 + src/schedule/svrstat.schedule.ts | 32 ++++++++++ src/service/WsSvr.ts | 15 +++++ 6 files changed, 158 insertions(+), 1 deletion(-) create mode 100644 src/schedule/svrstat.schedule.ts create mode 100644 src/service/WsSvr.ts diff --git a/package-lock.json b/package-lock.json index eac8019..1924b31 100644 --- a/package-lock.json +++ b/package-lock.json @@ -79,6 +79,14 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.20.tgz", "integrity": "sha512-Y93R97Ouif9JEOWPIUyU+eyIdyRqQR0I8Ez1dzku4hDx34NWh4HbtIc3WNzwB1Y9ULvNGeu5B8h8bVL5cAk4/A==" }, + "@types/node-schedule": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@types/node-schedule/-/node-schedule-1.3.2.tgz", + "integrity": "sha512-Y0CqdAr+lCpArT8CJJjJq4U2v8Bb5e7ru2nV/NhDdaptCMCRdOL3Y7tAhen39HluQMaIKWvPbDuiFBUQpg7Srw==", + "requires": { + "@types/node": "*" + } + }, "@types/redis": { "version": "2.8.28", "resolved": "https://registry.npmjs.org/@types/redis/-/redis-2.8.28.tgz", @@ -246,6 +254,15 @@ "dicer": "0.3.0" } }, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, "colors": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", @@ -272,6 +289,15 @@ "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", "dev": true }, + "cron-parser": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/cron-parser/-/cron-parser-3.5.0.tgz", + "integrity": "sha512-wyVZtbRs6qDfFd8ap457w3XVntdvqcwBGxBoTvJQH9KGVKL/fB+h2k3C8AqiVxvUQKN1Ps/Ns46CNViOpVDhfQ==", + "requires": { + "is-nan": "^1.3.2", + "luxon": "^1.26.0" + } + }, "cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -308,6 +334,14 @@ "execa": "^5.0.0" } }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "requires": { + "object-keys": "^1.0.12" + } + }, "denque": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/denque/-/denque-1.5.0.tgz", @@ -598,6 +632,21 @@ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "get-intrinsic": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + } + }, "get-stream": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.0.tgz", @@ -616,6 +665,19 @@ "path-is-absolute": "^1.0.0" } }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==" + }, "helmet": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/helmet/-/helmet-4.3.1.tgz", @@ -694,6 +756,15 @@ "ip-regex": "^4.0.0" } }, + "is-nan": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz", + "integrity": "sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==", + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" + } + }, "is-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", @@ -828,6 +899,11 @@ "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.7.1.tgz", "integrity": "sha512-Hesni4s5UkWkwCGJMQGAh71PaLUmKFM60dHvq0zi/vDhhrzuk+4GgNbTXJ12YYQJn6ZKBDNIjYcuQGKudvqrIw==" }, + "long-timeout": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/long-timeout/-/long-timeout-0.1.1.tgz", + "integrity": "sha1-lyHXiLR+C8taJMLivuGg2lXatRQ=" + }, "lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -836,6 +912,11 @@ "yallist": "^4.0.0" } }, + "luxon": { + "version": "1.28.0", + "resolved": "https://registry.npmjs.org/luxon/-/luxon-1.28.0.tgz", + "integrity": "sha512-TfTiyvZhwBYM/7QdAVDh+7dBTBA29v4ik0Ce9zda3Mnf8on1S5KJI8P2jKFZ8+5C0jhmr0KwJEO/Wdpm0VeWJQ==" + }, "make-error": { "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", @@ -1015,6 +1096,16 @@ "resolved": "https://registry.npmjs.org/node-bin-setup/-/node-bin-setup-1.0.6.tgz", "integrity": "sha512-uPIxXNis1CRbv1DwqAxkgBk5NFV3s7cMN/Gf556jSw6jBvV7ca4F9lRL/8cALcZecRibeqU+5dFYqFFmzv5a0Q==" }, + "node-schedule": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/node-schedule/-/node-schedule-2.0.0.tgz", + "integrity": "sha512-cHc9KEcfiuXxYDU+HjsBVo2FkWL1jRAUoczFoMIzRBpOA4p/NRHuuLs85AWOLgKsHtSPjN8csvwIxc2SqMv+CQ==", + "requires": { + "cron-parser": "^3.1.0", + "long-timeout": "0.1.1", + "sorted-array-functions": "^1.3.0" + } + }, "npm-run-path": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", @@ -1023,6 +1114,11 @@ "path-key": "^3.0.0" } }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" + }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -1298,6 +1394,11 @@ "flatstr": "^1.0.12" } }, + "sorted-array-functions": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/sorted-array-functions/-/sorted-array-functions-1.3.0.tgz", + "integrity": "sha512-2sqgzeFlid6N4Z2fUQ1cvFmTOLRi/sEDzSQ0OKYchqgoPmQBVyM3959qYx3fpS6Esef80KjmpgPeEr028dP3OA==" + }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", diff --git a/package.json b/package.json index 5b3d443..c413b92 100644 --- a/package.json +++ b/package.json @@ -32,6 +32,7 @@ "mongoose-findorcreate": "^3.0.0", "nanoid": "^3.1.20", "node": "^14.15.1", + "node-schedule": "^2.0.0", "redis": "^2.8.0", "tracer": "^1.1.4", "urlencode": "^1.1.0" @@ -41,6 +42,7 @@ "@types/mongoose": "5.10.3", "@types/node": "^14.14.20", "@types/redis": "^2.8.28", + "@types/node-schedule": "^1.3.2", "ts-node": "^9.1.1", "tsconfig-paths": "^3.9.0", "typescript": "^4.1.3" diff --git a/src/api.server.ts b/src/api.server.ts index 01e95fe..4a95a78 100644 --- a/src/api.server.ts +++ b/src/api.server.ts @@ -19,6 +19,7 @@ import { registService, unRegistService } from './utils/system.util' +import { SvrStatSchedule } from './schedule/svrstat.schedule' const zReqParserPlugin = require('./plugins/zReqParser') const apiAuthPlugin = require('./plugins/apiauth') @@ -153,17 +154,22 @@ export class ApiServer { public async gracefullyShutdown(exit: boolean = true, err?: Error) { await unRegistService(this.port) } + + public registSchedult() { + new SvrStatSchedule().scheduleAll() + } public async start() { let self = this return new Promise(async (resolve, reject) => { await registerGracefulShutdown((err) => self.gracefullyShutdown(true, err)); await self.connectDB() - await self.initCache() + // await self.initCache() await registService(self.port) self.initControllers() self.registerRouter() self.setErrHandler() self.setFormatSend() + self.registSchedult() initData() this.server.listen({port: self.port}, (err: any, address: any) => { if (err) { diff --git a/src/common/Debug.ts b/src/common/Debug.ts index 095aba5..92993d7 100644 --- a/src/common/Debug.ts +++ b/src/common/Debug.ts @@ -11,6 +11,7 @@ export const robotLog = debug('jc:robot'); export const assistLog = debug('jc:assist'); export const cardLog = debug('jc:card'); +export const statLog = debug('jc:stat'); export const error = debug('jc:error'); error.log = console.error.bind(console); diff --git a/src/schedule/svrstat.schedule.ts b/src/schedule/svrstat.schedule.ts new file mode 100644 index 0000000..58dd9ba --- /dev/null +++ b/src/schedule/svrstat.schedule.ts @@ -0,0 +1,32 @@ +import { singleton } from '../decorators/singleton.decorator' +import { allSvrs, closeRoom } from '../service/WsSvr' +import * as schedule from 'node-schedule' +import logger from '../logger/logger' + +@singleton +export class SvrStatSchedule { + async parseAll() { + let { data } = await allSvrs() + logger.info(`check room state, rooms: ${data.rooms.length} ,connections: ${data.connections}, cpu: ${data.cpu}, memory: ${data.memory.usedMemMb} / ${data.memory.totalMemMb}`) + for (let room of data.rooms) { + if (room.name === 'general_room' && room.clients < 4 && room.elapsedTime >= 1200000) { // 20 * 60 * 1000 + logger.info(`room ${room.roomId} idle`) + try { + await closeRoom(room.roomId) + } catch { + logger.error(`room ${room.roomId} close error`) + } + } + } + } + + scheduleAll() { + const job = schedule.scheduleJob('1 * * * * *', async () => { + try { + await this.parseAll() + } catch (err) { + logger.error(err) + } + }) + } +} diff --git a/src/service/WsSvr.ts b/src/service/WsSvr.ts new file mode 100644 index 0000000..f52d430 --- /dev/null +++ b/src/service/WsSvr.ts @@ -0,0 +1,15 @@ +import axios from 'axios' + +// const apiBase = 'https://pokerhero.kingsome.cn/colyseus/api' +const apiBase = 'http://127.0.0.1:2567/colyseus/api' +export function allSvrs() { + const url = `${apiBase}` + return axios.get(url) +} + + +export function closeRoom(roomId: string) { + const url = `${apiBase}/room/call?roomId=${roomId}&method=disconnect&args=%5B%5D` + return axios.get(url) +} +