require('xprofiler').start(); import { COM_TEAM_STATUS, STATUS } from './app/consts'; import { createTcpAcceptor, createTcpMailBox, FrontendOrBackendSession, HandlerCallback, pinus, RESERVED, RouteRecord } from 'pinus'; import * as mongoose from 'mongoose'; import * as redisService from './app/services/redisService'; import './app/servers/user.rpc.define' import * as routeUtil from './app/util/routeUtil'; import { preload } from './preload'; var checkEventFilter = require('./app/servers/battle/filter/checkEventFilter'); import { connectRedis } from './config/redis'; import * as timeTaskService from './app/services/timeTaskService'; import * as redlockCacheService from './app/services/redlockCacheService'; import * as redLockService from './app/services/redLockService'; // TODO 需要整理。 import _pinus = require('pinus'); import { updateTeamStatus } from './app/services/comBattleService'; import { init } from './app/pubUtils/gmData/gmDataUtil'; import { resResult } from './app/pubUtils/util'; const filePath = (_pinus as any).FILEPATH; filePath.MASTER = '/config/master'; filePath.SERVER = '/config/servers'; filePath.CRON = '/config/crons'; filePath.LOG = '/config/log4js'; filePath.SERVER_PROTOS = '/config/serverProtos'; filePath.CLIENT_PROTOS = '/config/clientProtos'; filePath.MASTER_HA = '/config/masterha'; filePath.LIFECYCLE = '/lifecycle'; filePath.SERVER_DIR = '/app/servers/'; filePath.CONFIG_DIR = '/config'; const adminfilePath = _pinus.DEFAULT_ADMIN_PATH; adminfilePath.ADMIN_FILENAME = 'adminUser'; adminfilePath.ADMIN_USER = 'config/adminUser'; const ALL_ENVS = 'production|development|alpha|dev|isbn|monitor'; /** * 替换全局Promise * 自动解析sourcemap * 捕获全局错误 */ preload(); /** * Init app for client. */ let app = pinus.createApp(); app.set('name', 'chatofpomelo-websocket'); // 加载数据库和redis app.configure(function () { app.loadConfig('database', app.getBase() + '/config/database'); app.loadConfig('serverName', app.getBase() + '/config/serverName'); console.log('env:', app.get('env')); console.log('db:', app.get('database')); console.log('serverName:', app.get('serverName')) mongoose.connect(app.get('database').mongo, { useNewUrlParser: true, useUnifiedTopology: true, useCreateIndex: true, useFindAndModify: false }, (err) => { if (err) { console.log('mongodb connect err', err); } else { console.log('mongodb connect suc'); } }); const redisClient = connectRedis(app.get('database').redis, app.get('database').redispw); app.set('redis', redisClient); redLockService.initRedlock(redisClient); redlockCacheService.init(); // TODO 重启 1 次只需要初始化 1 次,判断方法可以优化 if (app.serverId === 'master-server-1') { redisService.readDataBase(); redisService.initAllRank(); redisService.clearComBtlQueue(); redisService.clearChannelServers(); updateTeamStatus(COM_TEAM_STATUS.DEFAULT, COM_TEAM_STATUS.LOOSE); updateTeamStatus(COM_TEAM_STATUS.FIGHTING, COM_TEAM_STATUS.LOOSE); } }); // app configuration app.configure(ALL_ENVS, 'connector', function () { app.set('connectorConfig', { connector: pinus.connectors.hybridconnector, heartbeat: 60, useDict: true, useProtobuf: true }); /** // 缓存大小不够 日志示例 [2020-03-27T10:44:48.752] [ERROR] pinus - [chat-server-1 channelService.js] [pushMessage] fail to dispatch msg to serverId: connector-server-1, err:RangeError [ERR_OUT_OF_RANGE]: The value of "offset" is out of range. It must be >= 0 and <= 0. Received 1 at boundsError (internal/buffer.js:53:9) at writeU_Int8 (internal/buffer.js:562:5) at Buffer.writeUInt8 (internal/buffer.js:569:10) at Encoder.writeBytes (F:\develop\gong4-server\logicServer\pinus\packages\pinus-protobuf\lib\encoder.ts:195:20) */ app.set('protobufConfig', { // protobuf Encoder 使用 5m 的缓存 需要保证每个消息不会超过指定的缓存大小,超过了就会抛出异常 encoderCacheSize: 5 * 1024 * 1024, // decode 对客户端请求消息做校验 decodeCheckMsg: true, }); }); app.configure(ALL_ENVS, 'gate', function () { app.set('connectorConfig', { connector: pinus.connectors.hybridconnector, useProtobuf: true }); }); app.configure(ALL_ENVS, 'gm', function () { app.set('connectorConfig', { connector: pinus.connectors.hybridconnector, useProtobuf: true }); init();//将gm后台数据加载到gate服 }); app.configure(ALL_ENVS, 'guild', function () { app.set('connectorConfig', { connector: pinus.connectors.hybridconnector, useProtobuf: true }); }); app.configure(ALL_ENVS, 'systimer', function () { app.set('connectorConfig', { connector: pinus.connectors.hybridconnector, useProtobuf: true }); timeTaskService.init(); }); function errorHandler(err: Error, msg: any, resp: any, session: FrontendOrBackendSession, cb: HandlerCallback) { console.error(`${pinus.app.serverId} error handler msg[${JSON.stringify(msg)}] ,resp[${JSON.stringify(resp)}] , to resolve unknown exception: sessionId:${JSON.stringify(session.export())} , error stack: ${err.stack}`); if (!resp) { resp = resResult(STATUS.GLOBAL_ERR); } cb(err, resp); } export function globalErrorHandler(err: Error, msg: any, resp: any, session: FrontendOrBackendSession, cb: HandlerCallback) { console.error(`${pinus.app.serverId} globalErrorHandler msg[${JSON.stringify(msg)}] ,resp[${JSON.stringify(resp)}] , to resolve unknown exception: sessionId:${JSON.stringify(session.export())} , error stack: ${err.stack}`); if (cb) { cb(err, resp ? resp : { code: 503 }); } } // app configure app.configure(ALL_ENVS, function () { app.set(RESERVED.ERROR_HANDLER, errorHandler); app.set(RESERVED.GLOBAL_ERROR_HANDLER, globalErrorHandler); app.globalAfter((err: Error, routeRecord: RouteRecord, msg: any, session: FrontendOrBackendSession, resp: any, cb: HandlerCallback) => { console.log('global after ', err, msg && msg.route, msg && JSON.stringify(msg.body), session && session.get('roleId')) }) app.globalBefore((routeRecord: RouteRecord, msg: any, session: FrontendOrBackendSession, cb: HandlerCallback) => { if (msg.body === null) { cb(new Error(`msg body ===null maybe protobuf check error uid:${session.uid} ${JSON.stringify(msg)}`), { code: 499 }); return; } cb(null); }); // route configures app.route('chat', routeUtil.chat); app.route('battle', routeUtil.battle); app.route('gm', routeUtil.gm); app.route('guild', routeUtil.guild); app.route('activity', routeUtil.activity); app.route('order', routeUtil.order); // filter configures app.filter(new pinus.filters.time()); app.filter(new pinus.filters.timeout()); app.filter(checkEventFilter(app)); // RPC 启用TCP协议 app.set('proxyConfig', { mailboxFactory: createTcpMailBox, // bufferMsg:true // rpc 超时时间 // timeout: 20 * 1000, // dynamicUserProxy: true, }); app.set('remoteConfig', { acceptorFactory: createTcpAcceptor, // bufferMsg:true, // interval:50, }); }); // TODO: 所有环境打开监听模块和日志 app.configure(ALL_ENVS, function () { // enable the system monitor modules app.enable('systemMonitor'); app.enable('rpcDebugLog'); }); if (app.isMaster()) { // app.use(createRobotPlugin({scriptFile: __dirname + '/robot/robot.js'})); } // start app app.start();