diff --git a/src/service/Service.ts b/src/service/Service.ts index 3062880..d23abef 100644 --- a/src/service/Service.ts +++ b/src/service/Service.ts @@ -1,10 +1,21 @@ import { singleton } from '../decorators/singleton.decorator' -import { getNodeList, listen, Action } from './discovery' +import { Action, getNodeList, listen } from './discovery' import { error, sysLog } from '../common/Debug' import { Config } from '../cfg/Config' import ip from 'internal-ip' +import { RedisClient } from '../redis/RedisClient' + const config: Config = require('../../config/config.json') const isProd = process.env.NODE_ENV === 'production' + +const NODES_SET = 'colyseus:nodes' +const ROOM_COUNT_KEY = 'roomcount' +const DISCOVERY_CHANNEL = 'colyseus:nodes:discovery'; + +interface Node { + processId: string; + address?: string +} @singleton export class Service { /** @@ -43,12 +54,12 @@ export class Service { public discoveryServices() { listen(Service.INFO_CHANNEL, (action: Action, address: string) => { - sysLog("LISTEN: info channel ", action, address); + sysLog('LISTEN: info channel ', action, address) if (action === 'add') { - this.register(Service.INFO_NODE, address); + this.register(Service.INFO_NODE, address) } else if (action == 'remove') { - this.unregister(Service.INFO_NODE, address); + this.unregister(Service.INFO_NODE, address) } }).then(() => { sysLog('subscribe to info channel success') @@ -56,18 +67,21 @@ export class Service { sysLog('subscribe to info channel error', err) }) listen(Service.ROBOT_CHANNEL, (action: Action, address: string) => { - sysLog("LISTEN: robot channel", action, address); + sysLog('LISTEN: robot channel', action, address) if (action === 'add') { - this.register(Service.ROBOT_NODE, address); + this.register(Service.ROBOT_NODE, address) } else if (action == 'remove') { - this.unregister(Service.ROBOT_NODE, address); + this.unregister(Service.ROBOT_NODE, address) } }).then(() => { sysLog('subscribe to robot channel success') }).catch(err => { sysLog('subscribe to robot channel error', err) }) + listen(DISCOVERY_CHANNEL, async (action: Action, message: string) => { + await this.cleanRedisData() + }).catch(err => {}) } public async getInfoSvr() { @@ -81,7 +95,7 @@ export class Service { error('no info service found') return config.info_svr } - return 'http://' + svrList.randomOne()+'/svr' + return 'http://' + svrList.randomOne() + '/svr' } public async getRobotSvr() { @@ -98,18 +112,40 @@ export class Service { return 'http://' + svrList.randomOne() } + public async registSelf(port: number) { + const host = process.env.SELF_HOSTNAME || await ip.v4() + this.selfHost = `ws://${ host }:${ port }` + } + private register(type: string, address: string) { let svrList = this.serviceMap.get(type) svrList.pushOnce(address) } + private unregister(type: string, address: string) { let svrList = this.serviceMap.get(type) svrList.removeEx(address) } - public async registSelf(port: number) { - const host = process.env.SELF_HOSTNAME || await ip.v4(); - this.selfHost = `ws://${host}:${port}` - } + /** + * 清理redis中roomcount的值 + * @return {Promise} + */ + public async cleanRedisData() { + const client = new RedisClient() + const parseNode = function (data: string): Node { + const [processId, address] = data.split("/"); + return { processId, address }; + } + const nodeStrs: string[] = await client.smembers(NODES_SET) + const nodes = nodeStrs.map(data => parseNode(data)) + const nodeMap = nodes.toMap('processId') + const countObjs = await client.hgetall(ROOM_COUNT_KEY) + for (let key of Object.keys(countObjs)) { + if (!nodeMap.has(key)) { + await client.hdel(ROOM_COUNT_KEY, key) + } + } + } }