From f15b6319e39f75383a7ed2716f4b52d5419ccdd1 Mon Sep 17 00:00:00 2001 From: luying Date: Fri, 7 Jan 2022 18:55:28 +0800 Subject: [PATCH] =?UTF-8?q?=E6=97=A5=E5=BF=97=EF=BC=9A=E5=A4=84=E7=90=86?= =?UTF-8?q?=E6=97=A5=E5=BF=97=E4=BF=9D=E5=AD=98=E6=95=B0=E9=87=8F=E3=80=81?= =?UTF-8?q?=E5=A4=A7=E5=B0=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/servers/connector/filter/global.ts | 4 +- game-server/channelService.js | 522 ++++++++++++++++++ game-server/config/sq1/log4js.ts | 10 +- game-server/pm2Starter.sh | 3 +- game-server/pm2StarterDistribute.sh | 1 + shared/pubUtils/dicParam.ts | 2 +- 6 files changed, 533 insertions(+), 9 deletions(-) create mode 100644 game-server/channelService.js diff --git a/game-server/app/servers/connector/filter/global.ts b/game-server/app/servers/connector/filter/global.ts index 63702fbec..1838ec1c1 100644 --- a/game-server/app/servers/connector/filter/global.ts +++ b/game-server/app/servers/connector/filter/global.ts @@ -8,7 +8,7 @@ import { UserModel } from "../../../db/User"; import { SERVER_DEBUG_MODE } from "../../../pubUtils/dicParam"; import { nowSeconds } from "../../../pubUtils/timeUtil"; import { getServerMainten } from "../../../services/gmService"; -import { errlogger } from "../../../util/logger"; +// import { errlogger } from "../../../util/logger"; export function globalFilter(app: Application) { return new Filter(app); } @@ -32,7 +32,7 @@ Filter.prototype.before = async function (routeRecord: RouteRecord, msg: any, se if(this.accessTime && this.accessTime.has(keyOfRouteWithUser)) { console.log(this.accessTime.get(keyOfRouteWithUser) - Date.now()); if(Date.now() - this.accessTime.get(keyOfRouteWithUser) < ACCESS_FREQUENCY) { - errlogger.error(`${keyOfRouteWithUser} 间隔时间小于${ACCESS_FREQUENCY}ms,为 ${Date.now() - this.accessTime.get(keyOfRouteWithUser)}`); + // errlogger.error(`${keyOfRouteWithUser} 间隔时间小于${ACCESS_FREQUENCY}ms,为 ${Date.now() - this.accessTime.get(keyOfRouteWithUser)}`); // return next(new Error(), resResult(STATUS.ACCESS_BUSY)); } } diff --git a/game-server/channelService.js b/game-server/channelService.js new file mode 100644 index 000000000..e3d51dcd0 --- /dev/null +++ b/game-server/channelService.js @@ -0,0 +1,522 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const countDownLatch = require("../../util/countDownLatch"); +const utils = require("../../util/utils"); +const channelRemote_1 = require("../remote/frontend/channelRemote"); +const pinus_logger_1 = require("pinus-logger"); +const path = require("path"); +let logger = pinus_logger_1.getLogger('pinus', path.basename(__filename)); +let infoLogger = pinus_logger_1.getLogger('info', path.basename(__filename)); +/** + * constant + */ +let ST_INITED = 0; +let ST_DESTROYED = 1; +/** + * Create and maintain channels for server local. + * + * ChannelService is created by channel component which is a default loaded + * component of pinus and channel service would be accessed by `app.get('channelService')`. + * + * @class + * @constructor + */ +class ChannelService { + constructor(app, opts) { + this.apushMessageByUids = utils.promisify(this.pushMessageByUids); + this.abroadcast = utils.promisify(this.broadcast); + opts = opts || {}; + this.app = app; + this.channels = {}; + this.prefix = opts.prefix; + this.store = opts.store; + this.broadcastFilter = opts.broadcastFilter; + this.channelRemote = new channelRemote_1.ChannelRemote(app); + } + start(cb) { + restoreChannel(this, cb); + } + /** + * Create channel with name. + * + * @param {String} name channel's name + * @memberOf ChannelService + */ + createChannel(name) { + if (this.channels[name]) { + return this.channels[name]; + } + let c = new Channel(name, this); + addToStore(this, genKey(this), genKey(this, name)); + this.channels[name] = c; + return c; + } + /** + * Get channel by name. + * + * @param {String} name channel's name + * @param {Boolean} create if true, create channel + * @return {Channel} + * @memberOf ChannelService + */ + getChannel(name, create) { + let channel = this.channels[name]; + if (!channel && !!create) { + channel = this.channels[name] = new Channel(name, this); + addToStore(this, genKey(this), genKey(this, name)); + } + return channel; + } + /** + * Destroy channel by name. + * + * @param {String} name channel name + * @memberOf ChannelService + */ + destroyChannel(name) { + delete this.channels[name]; + removeFromStore(this, genKey(this), genKey(this, name)); + removeAllFromStore(this, genKey(this, name)); + } + pushMessageByUids(route, msg, uids, opts, cb) { + if (typeof route !== 'string') { + cb = opts; + opts = uids; + uids = msg; + msg = route; + route = msg.route; + } + if (!cb && typeof opts === 'function') { + cb = opts; + opts = {}; + } + if (!uids || uids.length === 0) { + utils.invokeCallback(cb, new Error('uids should not be empty')); + return; + } + let groups = {}, record; + for (let i = 0, l = uids.length; i < l; i++) { + record = uids[i]; + add(record.uid, record.sid, groups); + } + sendMessageByGroup(this, route, msg, groups, opts, cb); + } + broadcast(stype, route, msg, opts, cb) { + let app = this.app; + let namespace = 'sys'; + let service = 'channelRemote'; + let method = 'broadcast'; + let servers = app.getServersByType(stype); + if (!servers || servers.length === 0) { + // server list is empty + utils.invokeCallback(cb); + return; + } + if (!cb && typeof opts === 'function') { + cb = opts; + opts = undefined; + } + let count = servers.length; + let successFlag = false; + let latch = countDownLatch.createCountDownLatch(count, function () { + if (!successFlag) { + utils.invokeCallback(cb, new Error('broadcast fails')); + return; + } + utils.invokeCallback(cb, null); + }); + let genCB = function (serverId) { + return function (err) { + if (err) { + logger.error('[broadcast] fail to push message to serverId: ' + serverId + ', err:' + err.stack); + infoLogger.error('[broadcast] fail to push message to serverId: ' + serverId + ', err:' + err.stack); + latch.done(); + return; + } + successFlag = true; + latch.done(); + }; + }; + opts = { type: 'broadcast', userOptions: opts || {} }; + // for compatiblity + opts.isBroadcast = true; + if (opts.userOptions) { + opts.binded = opts.userOptions.binded; + opts.filterParam = opts.userOptions.filterParam; + } + let self = this; + let sendMessage = function (serverId) { + return (function () { + if (serverId === app.serverId) { + self.channelRemote[method](route, msg, opts).then(() => genCB(serverId)(null)).catch((err) => genCB(serverId)(err)); + } + else { + app.rpcInvoke(serverId, { + namespace: namespace, service: service, + method: method, args: [route, msg, opts] + }, genCB(serverId)); + } + }()); + }; + for (let i = 0, l = count; i < l; i++) { + sendMessage(servers[i].id); + } + } +} +exports.ChannelService = ChannelService; +/** + * Channel maintains the receiver collection for a subject. You can + * add users into a channel and then broadcast message to them by channel. + * + * @class channel + * @constructor + */ +class Channel { + constructor(name, service) { + this.apushMessage = utils.promisify(this.pushMessage); + this.name = name; + this.groups = {}; // group map for uids. key: sid, value: [uid] + this.records = {}; // member records. key: uid + this.__channelService__ = service; + this.state = ST_INITED; + this.userAmount = 0; + } + /** + * Add user to channel. + * + * @param {Number} uid user id + * @param {String} sid frontend server id which user has connected to + */ + add(uid, sid) { + if (this.state > ST_INITED) { + return false; + } + else { + let res = add(uid, sid, this.groups); + if (res) { + this.records[uid] = { sid: sid, uid: uid }; + this.userAmount = this.userAmount + 1; + addToStore(this.__channelService__, genKey(this.__channelService__, this.name), genValue(sid, uid)); + } + return res; + } + } + /** + * Remove user from channel. + * + * @param {Number} uid user id + * @param {String} sid frontend server id which user has connected to. + * @return [Boolean] true if success or false if fail + */ + leave(uid, sid) { + if (!uid || !sid) { + return false; + } + let res = deleteFrom(uid, sid, this.groups[sid]); + if (res) { + delete this.records[uid]; + this.userAmount = this.userAmount - 1; + removeFromStore(this.__channelService__, genKey(this.__channelService__, this.name), genValue(sid, uid)); + } + if (this.userAmount < 0) + this.userAmount = 0; // robust + if (this.groups[sid] && this.groups[sid].length === 0) { + delete this.groups[sid]; + } + return res; + } + /** + * Get channel UserAmount in a channel. + * + * @return {number } channel member amount + */ + getUserAmount() { + return this.userAmount; + } + /** + * Get channel members. + * + * Notice: Heavy operation. + * + * @return {Array} channel member uid list + */ + getMembers() { + let res = [], groups = this.groups; + let group, i, l; + for (let sid in groups) { + group = groups[sid]; + for (i = 0, l = group.length; i < l; i++) { + res.push(group[i]); + } + } + return res; + } + /** + * Get Member info. + * + * @param {String} uid user id + * @return {Object} member info + */ + getMember(uid) { + return this.records[uid]; + } + /** + * Remove member by uid + * @param uid member to removed + */ + removeMember(uid) { + let member = this.getMember(uid); + if (member) + return this.leave(member.uid, member.sid); + else + return false; + } + /** + * Destroy channel. + */ + destroy() { + this.state = ST_DESTROYED; + this.__channelService__.destroyChannel(this.name); + } + /** + * Push message to all the members in the channel + * + * @param {String} route message route + * @param {Object} msg message that would be sent to client + * @param {Object} opts user-defined push options, optional + * @param {Function} cb callback function + */ + pushMessage(route, msg, opts, cb) { + if (this.state !== ST_INITED) { + utils.invokeCallback(cb, new Error('channel is not running now')); + return; + } + if (typeof route !== 'string') { + cb = opts; + opts = msg; + msg = route; + route = msg.route; + } + if (!cb && typeof opts === 'function') { + cb = opts; + opts = {}; + } + sendMessageByGroup(this.__channelService__, route, msg, this.groups, opts, cb); + } +} +exports.Channel = Channel; +/** + * add uid and sid into group. ignore any uid that uid not specified. + * + * @param uid user id + * @param sid server id + * @param groups {Object} grouped uids, , key: sid, value: [uid] + */ +let add = function (uid, sid, groups) { + if (!sid) { + logger.warn('ignore uid %j for sid not specified.', uid); + infoLogger.warn('ignore uid %j for sid not specified.', uid); + return false; + } + let group = groups[sid]; + if (!group) { + group = []; + groups[sid] = group; + } + group.push(uid); + return true; +}; +/** + * delete element from array + */ +let deleteFrom = function (uid, sid, group) { + if (!uid || !sid || !group) { + return false; + } + for (let i = 0, l = group.length; i < l; i++) { + if (group[i] === uid) { + group.splice(i, 1); + return true; + } + } + return false; +}; +/** + * push message by group + * + * @param route {String} route route message + * @param msg {Object} message that would be sent to client + * @param groups {Object} grouped uids, , key: sid, value: [uid] + * @param opts {Object} push options + * @param cb {Function} cb(err) + * + * @api private + */ +let sendMessageByGroup = function (channelService, route, msg, groups, opts, cb) { + let app = channelService.app; + let namespace = 'sys'; + let service = 'channelRemote'; + let method = 'pushMessage'; + let count = Object.keys(groups).length; + let successFlag = false; + let failIds = []; + logger.debug('[%s] channelService sendMessageByGroup route: %s, msg: %j, groups: %j, opts: %j', app.serverId, route, msg, groups, opts); + infoLogger.debug('[%s] channelService sendMessageByGroup route: %s, msg: %j, groups: %j, opts: %j', app.serverId, route, msg, groups, opts); + if (count === 0) { + // group is empty + utils.invokeCallback(cb); + return; + } + let latch = countDownLatch.createCountDownLatch(count, function () { + if (!successFlag) { + utils.invokeCallback(cb, new Error('all uids push message fail')); + return; + } + utils.invokeCallback(cb, null, failIds); + }); + let rpcCB = function (serverId) { + return function (err, fails) { + if (err) { + logger.error('[pushMessage] fail to dispatch msg to serverId: ' + serverId + ', err:' + err.stack); + infoLogger.error('[pushMessage] fail to dispatch msg to serverId: ' + serverId + ', err:' + err.stack); + latch.done(); + return; + } + if (fails) { + failIds = failIds.concat(fails); + } + successFlag = true; + latch.done(); + }; + }; + opts = { type: 'push', userOptions: opts || {} }; + // for compatiblity + opts.isPush = true; + let sendMessage = function (sid) { + return (function () { + if (sid === app.serverId) { + channelService.channelRemote[method](route, msg, groups[sid], opts).then((fails) => { + rpcCB(sid)(null, fails); + }, (err) => { + rpcCB(sid)(err, null); + }); + } + else { + app.rpcInvoke(sid, { + namespace: namespace, service: service, + method: method, args: [route, msg, groups[sid], opts] + }, rpcCB(sid)); + } + })(); + }; + let group; + for (let sid in groups) { + group = groups[sid]; + if (group && group.length > 0) { + sendMessage(sid); + } + else { + // empty group + process.nextTick(rpcCB(sid)); + } + } +}; +let restoreChannel = function (self, cb) { + if (!self.store) { + utils.invokeCallback(cb); + return; + } + else { + loadAllFromStore(self, genKey(self), function (err, list) { + if (!!err) { + utils.invokeCallback(cb, err); + return; + } + else { + if (!list.length || !Array.isArray(list)) { + utils.invokeCallback(cb); + return; + } + let load = function (key, name) { + return (function () { + let channelName = name; + loadAllFromStore(self, key, function (err, items) { + for (let j = 0; j < items.length; j++) { + let array = items[j].split(':'); + let sid = array[0]; + let uid = array[1]; + let channel = self.channels[channelName]; + let res = add(uid, sid, channel.groups); + if (res) { + channel.records[uid] = { sid: sid, uid: uid }; + } + } + }); + })(); + }; + for (let i = 0; i < list.length; i++) { + let name = list[i].slice(genKey(self).length + 1); + self.channels[name] = new Channel(name, self); + load(list[i], name); + } + utils.invokeCallback(cb); + } + }); + } +}; +let addToStore = function (self, key, value) { + if (!!self.store) { + self.store.add(key, value, function (err) { + if (!!err) { + logger.error('add key: %s value: %s to store, with err: %j', key, value, err); + infoLogger.error('add key: %s value: %s to store, with err: %j', key, value, err); + } + }); + } +}; +let removeFromStore = function (self, key, value) { + if (!!self.store) { + self.store.remove(key, value, function (err) { + if (!!err) { + logger.error('remove key: %s value: %s from store, with err: %j', key, value, err); + infoLogger.error('remove key: %s value: %s from store, with err: %j', key, value, err); + } + }); + } +}; +let loadAllFromStore = function (self, key, cb) { + if (!!self.store) { + self.store.load(key, function (err, list) { + if (!!err) { + logger.error('load key: %s from store, with err: %j', key, err); + infoLogger.error('load key: %s from store, with err: %j', key, err); + utils.invokeCallback(cb, err); + } + else { + utils.invokeCallback(cb, null, list); + } + }); + } +}; +let removeAllFromStore = function (self, key) { + if (!!self.store) { + self.store.removeAll(key, function (err) { + if (!!err) { + logger.error('remove key: %s all members from store, with err: %j', key, err); + infoLogger.error('remove key: %s all members from store, with err: %j', key, err); + } + }); + } +}; +let genKey = function (self, name) { + if (!!name) { + return self.prefix + ':' + self.app.serverId + ':' + name; + } + else { + return self.prefix + ':' + self.app.serverId; + } +}; +let genValue = function (sid, uid) { + return sid + ':' + uid; +}; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hhbm5lbFNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9saWIvY29tbW9uL3NlcnZpY2UvY2hhbm5lbFNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSw0REFBNEQ7QUFDNUQsMENBQTBDO0FBQzFDLG9FQUFpRTtBQUNqRSwrQ0FBeUM7QUFNekMsNkJBQTZCO0FBRTdCLElBQUksTUFBTSxHQUFHLHdCQUFTLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQztBQUUzRDs7R0FFRztBQUNILElBQUksU0FBUyxHQUFHLENBQUMsQ0FBQztBQUNsQixJQUFJLFlBQVksR0FBRyxDQUFDLENBQUM7QUFRckI7Ozs7Ozs7O0dBUUc7QUFDSCxNQUFhLGNBQWM7SUFTdkIsWUFBWSxHQUFnQixFQUFFLElBQTZCO1FBdUwzRCx1QkFBa0IsR0FBb0csS0FBSyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsQ0FBQztRQUM5SixlQUFVLEdBQTBFLEtBQUssQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBdkxoSCxJQUFJLEdBQUcsSUFBSSxJQUFJLEVBQUUsQ0FBQztRQUNsQixJQUFJLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQztRQUNmLElBQUksQ0FBQyxRQUFRLEdBQUcsRUFBRSxDQUFDO1FBQ25CLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztRQUMxQixJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUM7UUFDeEIsSUFBSSxDQUFDLGVBQWUsR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDO1FBQzVDLElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSw2QkFBYSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ2hELENBQUM7SUFHRCxLQUFLLENBQUMsRUFBeUI7UUFDM0IsY0FBYyxD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 \ No newline at end of file diff --git a/game-server/config/sq1/log4js.ts b/game-server/config/sq1/log4js.ts index 93bb0e1fd..33f3a5881 100644 --- a/game-server/config/sq1/log4js.ts +++ b/game-server/config/sq1/log4js.ts @@ -61,11 +61,11 @@ module.exports = { 'pinus': { 'type': 'file', 'filename': '/zyz_logs/log4js/pinus-${opts:serverId}.log', - 'maxLogSize': 1048576, + 'maxLogSize': 1073741824, 'layout': { 'type': 'basic' }, - 'backups': 5 + 'backups': 20 }, 'pinus-admin': { 'type': 'file', @@ -88,16 +88,16 @@ module.exports = { 'app': { 'type': 'file', 'filename': '/zyz_logs/sls/app.log', - 'maxLogSize': 10485760, + 'maxLogSize': 1073741824, 'layout': { 'type': 'basic' }, - 'backups': 15 + 'backups': 20 }, 'error': { 'type': 'file', 'filename': '/zyz_logs/sls/error.log', - 'maxLogSize': 1048576, + 'maxLogSize': 1073741824, 'layout': { 'type': 'basic' }, diff --git a/game-server/pm2Starter.sh b/game-server/pm2Starter.sh index 615735a1d..65e1dc0b8 100755 --- a/game-server/pm2Starter.sh +++ b/game-server/pm2Starter.sh @@ -1,5 +1,6 @@ #/bin/bash npm install #安装依赖库 +cp ./channelService.js ./node_modules/pinus/dist/lib/common/service/channelService.js npm run build node pm2Config.js #使用pm2来做进程管理,生成进程配置文件 -pm2 start pomeloPm2Start.json #pm2 启动游戏服务器 +pm2 start pomeloPm2Start.json #pm2 启动游戏服务器 \ No newline at end of file diff --git a/game-server/pm2StarterDistribute.sh b/game-server/pm2StarterDistribute.sh index d017a743b..5e8493f11 100755 --- a/game-server/pm2StarterDistribute.sh +++ b/game-server/pm2StarterDistribute.sh @@ -9,6 +9,7 @@ if [ $# != 2 ] ; then fi npm install #安装依赖库 +cp ./channelService.js ./node_modules/pinus/dist/lib/common/service/channelService.js npm run build node pm2DistributeConfig.js ${1} ${2} #使用pm2来做进程管理,生成进程配置文件 pm2 start pomeloPm2Start.json #pm2 启动游戏服务器 diff --git a/shared/pubUtils/dicParam.ts b/shared/pubUtils/dicParam.ts index c2d1335d0..7ed12003c 100644 --- a/shared/pubUtils/dicParam.ts +++ b/shared/pubUtils/dicParam.ts @@ -238,7 +238,7 @@ export const GK_MAINELITE = { GKMAINELITE_OPEN_CONDITION: 424, // 梦魇模式开启时间:通过某关卡id }; export const SERVER_DEBUG_MODE = { - CURRENT_TIME: 1, // 服务器是否打开推送时间debug模式 + CURRENT_TIME: 0, // 服务器是否打开推送时间debug模式 CHECK_WORD: 1, // 服务器是否打开屏蔽词校验debug模式 }; export const IS_SQ = {