353 lines
12 KiB
TypeScript
353 lines
12 KiB
TypeScript
require('xprofiler').start({
|
|
log_dir: '/zyz_logs/xprofiler',
|
|
});
|
|
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';
|
|
import { globalFilter } from'./app/servers/connector/filter/global';
|
|
import { guildAuthFilter } from'./app/servers/guild/filter/guildAuthFilter';
|
|
import { tokenFilter } from'./app/servers/gm/filter/tokenFilter';
|
|
import { connectRedis } from './app/pubUtils/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/battle/comBattleService';
|
|
import { resResult, genCode } from './app/pubUtils/util';
|
|
import { errlogger, infologger, loadLogger } from './app/util/logger';
|
|
import { connectThinkingData, getTire } from './app/services/sdkService';
|
|
import { loadSubDb, loadGmDb } from './app/db';
|
|
import { loadActivities } from './app/services/memoryCache/activityData';
|
|
import { checkAndSetApiIsClose } from './app/services/chatService';
|
|
import { initGuildActivityIndexInPinus, resetJoinWoodenHorse } from './app/services/guildActivity/guildActivityService';
|
|
import { setGVGConfig } from './app/services/gvg/gvgService';
|
|
import { isDevelopEnv } from './app/services/utilService';
|
|
import { initTeamToMem } from './app/services/gvg/gvgBattleService';
|
|
import { setServerGroup } from './app/services/serverService';
|
|
// 管理相关模块
|
|
import { UpdateComponent } from './app/components/UpdateComponent';
|
|
import { EvalComponent } from './app/components/EvalComponent';
|
|
import { UsrAdminModule } from './app/modules/UsrAdmin';
|
|
|
|
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 = 'stable|development|alpha|dev|isbn|isbnhk|monitor|monitor2|distribute|sq1|sq3|sq4|sq7|sq9|zy1|yjzios|ch1|zytest';
|
|
/**
|
|
* 替换全局Promise
|
|
* 自动解析sourcemap
|
|
* 捕获全局错误
|
|
*/
|
|
preload();
|
|
if (process.env.NODE_PROCESS_TITLE) {
|
|
process.title = process.env.NODE_PROCESS_TITLE;
|
|
}
|
|
|
|
console.log('process.env.NODE_ENV:', process.env.NODE_PROCESS_TITLE);
|
|
|
|
/**
|
|
* Init app for client.
|
|
*/
|
|
let app = pinus.createApp();
|
|
app.set('name', 'zyz');
|
|
|
|
// 全局配置,对所有 env 所有 serverType 生效
|
|
app.configure(function () {
|
|
app.loadConfig('database', app.getBase() + '/config/database');
|
|
console.log('env:', app.get('env'));
|
|
console.log('db:', app.get('database'));
|
|
|
|
setupRoutes(app);
|
|
setupFilters(app);
|
|
connectThinkingData(app);
|
|
loadLogger(app.getServerId());
|
|
treatStartLogic(app);
|
|
|
|
app.set(RESERVED.ERROR_HANDLER, errorHandler);
|
|
app.set(RESERVED.GLOBAL_ERROR_HANDLER, globalErrorHandler);
|
|
// RPC 启用TCP协议
|
|
app.set('proxyConfig', {
|
|
mailboxFactory: createTcpMailBox,
|
|
// bufferMsg:true
|
|
// rpc 超时时间
|
|
// timeout: 20 * 1000,
|
|
// dynamicUserProxy: true,
|
|
});
|
|
app.set('remoteConfig', {
|
|
acceptorFactory: createTcpAcceptor,
|
|
// bufferMsg:true,
|
|
// interval:50,
|
|
});
|
|
app.set('serverConfig', {
|
|
'reloadHandlers': true,
|
|
'reloadRemotes': true,
|
|
});
|
|
|
|
app.load(UpdateComponent, { app: app });
|
|
app.load(EvalComponent, { app: app });
|
|
});
|
|
|
|
// 对所有 env 的 个别 serverType 进行配置
|
|
app.configure(ALL_ENVS, 'connector', function () {
|
|
app.set('connectorConfig',
|
|
{
|
|
connector: pinus.connectors.hybridconnector,
|
|
heartbeat: 60,
|
|
useDict: false,
|
|
useProtobuf: true
|
|
});
|
|
|
|
app.set('protobufConfig', {
|
|
// protobuf Encoder 使用 5m 的缓存 需要保证每个消息不会超过指定的缓存大小,超过了就会抛出异常
|
|
encoderCacheSize: 5 * 1024 * 1024,
|
|
// decode 对客户端请求消息做校验
|
|
decodeCheckMsg: true,
|
|
});
|
|
});
|
|
|
|
// wss加密
|
|
// app.configure('sq1', 'connector', function() {
|
|
// app.set('connectorConfig',
|
|
// {
|
|
// connector: pinus.connectors.hybridconnector,
|
|
// heartbeat: 60,
|
|
// useDict: true,
|
|
// useProtobuf: true,
|
|
// ssl: {
|
|
// type: 'wss',
|
|
// key: fs.readFileSync('/usr/local/nginx/conf/cert/*.37wan.com.key'),
|
|
// cert: fs.readFileSync('/usr/local/nginx/conf/cert/*.37wan.com_with_chain.crt'),
|
|
// }
|
|
// });
|
|
// });
|
|
|
|
app.configure(ALL_ENVS, 'gate', function () {
|
|
app.set('connectorConfig',
|
|
{
|
|
connector: pinus.connectors.hybridconnector,
|
|
useProtobuf: true
|
|
});
|
|
});
|
|
|
|
app.configure(ALL_ENVS, 'guild', function () {
|
|
app.filter(guildAuthFilter(app));
|
|
})
|
|
|
|
app.configure(ALL_ENVS, 'gm', function () {
|
|
app.filter(tokenFilter(app));
|
|
});
|
|
|
|
app.registerAdmin(UsrAdminModule, {app: app});
|
|
|
|
function errorHandler(err: Error, msg: any, resp: any,
|
|
session: FrontendOrBackendSession, cb: HandlerCallback) {
|
|
const errCode = genCode(10);
|
|
if(err.message == 'globalFilter') {
|
|
infologger.debug('global after ', msg && msg.logCode, msg && JSON.stringify(msg), resp && JSON.stringify(resp), session && session.get('roleId'));
|
|
} else {
|
|
errlogger.error(`${pinus.app.serverId} error handler \n msg[${JSON.stringify(msg)}] \n resp[${JSON.stringify(resp)}] \n sessionId:${JSON.stringify(session.export())} \n error 【${errCode}】 stack: ${err.stack}`);
|
|
}
|
|
|
|
if (!resp) {
|
|
resp = resResult(STATUS.GLOBAL_ERR, { errCode, stack: err.stack });
|
|
}
|
|
cb(err, resp);
|
|
}
|
|
|
|
export function globalErrorHandler(err: Error, msg: any, resp: any,
|
|
session: FrontendOrBackendSession, cb: HandlerCallback) {
|
|
const errCode = genCode(10);
|
|
errlogger.error(`${pinus.app.serverId} globalErrorHandler handler \n msg[${JSON.stringify(msg)}] \n resp[${JSON.stringify(resp)}] \n sessionId:${JSON.stringify(session.export())} \n error 【${errCode}】 stack: ${err.stack}`);
|
|
|
|
if (cb) {
|
|
cb(err, resp ? resp : { code: 503 });
|
|
}
|
|
}
|
|
|
|
async function treatStartLogic(app: _pinus.Application) {
|
|
await connectDb(app);
|
|
console.log('treatStartLogic', app.getServerType());
|
|
|
|
if(app.getServerType() == 'systimer') {
|
|
redisService.redisSubScribe();
|
|
timeTaskService.init();
|
|
initGuildActivityIndexInPinus();
|
|
}
|
|
if(app.getServerType() == 'chat' && !isDevelopEnv()) {
|
|
getTire();
|
|
}
|
|
if(app.getServerType() == 'activity') {
|
|
loadActivities();
|
|
}
|
|
treatStartMainten(app);
|
|
checkAndSetApiIsClose();
|
|
if(app.getServerType() == 'guild') {
|
|
initGuildActivityIndexInPinus()
|
|
.then(resetJoinWoodenHorse);
|
|
}
|
|
if(app.getServerType() == 'battle'|| app.getServerType() == 'role'|| app.getServerType() == 'connector') {
|
|
timeTaskService.setPvpSeasonNum();
|
|
timeTaskService.setPvpSettleSeasonNum();
|
|
}
|
|
if(app.getServerType() != 'systimer') {
|
|
timeTaskService.initHiddenData();
|
|
}
|
|
if(app.getServerType() == 'battle'|| app.getServerType() == 'guild'|| app.getServerType() == 'chat'|| app.getServerType() == 'connector' || app.getServerType() == 'systimer' || app.getServerType() == 'gm') {
|
|
setServerGroup();
|
|
}
|
|
if(app.getServerType() == 'guild') {
|
|
setGVGConfig()
|
|
app.event.on('start_all', () => {
|
|
setGVGConfig().then(initTeamToMem);
|
|
});
|
|
}
|
|
|
|
if(app.isMaster()) {
|
|
redisService.initAllRank();
|
|
redisService.readDataBase();
|
|
redisService.clearComBtlQueue();
|
|
redisService.clearChannelServers();
|
|
redisService.clearGVGHistoryAreas();
|
|
redisService.clearGVGHistoryAreaTeam();
|
|
redisService.clearGVGHistoryCityTeam();
|
|
redisService.resetMaxOnlineUsers();
|
|
updateTeamStatus(COM_TEAM_STATUS.DEFAULT, COM_TEAM_STATUS.LOOSE);
|
|
updateTeamStatus(COM_TEAM_STATUS.FIGHTING, COM_TEAM_STATUS.LOOSE);
|
|
}
|
|
}
|
|
|
|
async function treatStartMainten(app: _pinus.Application) {
|
|
if(app.getServerType() == 'systimer') {
|
|
// 维护信息
|
|
await timeTaskService.initMaintenance(undefined, true);
|
|
} else {
|
|
await timeTaskService.initMaintenanaceInOtherServers();
|
|
}
|
|
}
|
|
|
|
async function connectDb(app: _pinus.Application) {
|
|
// Promise并行处理
|
|
return Promise.all([
|
|
initMongodb(app),
|
|
initSubMongodb(app),
|
|
initGmMongodb(app),
|
|
initRedis(app)
|
|
])
|
|
}
|
|
|
|
async function initMongodb(app: _pinus.Application) {
|
|
await mongoose.connect(app.get('database').mongo, { useNewUrlParser: true, useUnifiedTopology: true, useCreateIndex: true, useFindAndModify: false }, (err) => {
|
|
if (err) {
|
|
errlogger.error('mongodb connect err', err);
|
|
} else {
|
|
console.log('mongodb connect suc');
|
|
}
|
|
});
|
|
}
|
|
|
|
async function initSubMongodb(app: _pinus.Application) {
|
|
let connect = await mongoose.createConnection(app.get('database').mongoSub||app.get('database').mongo, { useNewUrlParser: true, useUnifiedTopology: true, useCreateIndex: true, useFindAndModify: false });
|
|
loadSubDb(connect);
|
|
console.log('subMongo connect suc')
|
|
}
|
|
async function initGmMongodb(app: _pinus.Application) {
|
|
let gmconnect = await mongoose.createConnection(app.get('database').gmmongo, { useNewUrlParser: true, useUnifiedTopology: true, useCreateIndex: true, useFindAndModify: false });
|
|
loadGmDb(gmconnect);
|
|
console.log('mongoGmDb connect suc')
|
|
}
|
|
function initRedis(app: _pinus.Application) {
|
|
const redisClient = connectRedis(app.get('database').redis, app.get('database').redispw);
|
|
app.set('redis', redisClient);
|
|
const redisClientPub = connectRedis(app.get('database').redis, app.get('database').redispw);
|
|
app.set('redisPub', redisClientPub); // 发布订阅机
|
|
// app.set('redis', redisClient);
|
|
const redisClientLock = connectRedis(app.get('database').redisLock||app.get('database').redis, app.get('database').redisLockpw||app.get('database').redispw);
|
|
redLockService.initRedlock(redisClientLock);
|
|
redlockCacheService.init();
|
|
}
|
|
|
|
function setupRoutes(app: _pinus.Application) {
|
|
app.route('chat', routeUtil.chat);
|
|
app.route('battle', routeUtil.battle);
|
|
app.route('comBattle', routeUtil.comBattle);
|
|
app.route('gm', routeUtil.gm);
|
|
app.route('guild', routeUtil.guild);
|
|
app.route('activity', routeUtil.activity);
|
|
app.route('order', routeUtil.order);
|
|
app.route('role', routeUtil.role);
|
|
}
|
|
|
|
function setupFilters(app: _pinus.Application) {
|
|
// filter configures
|
|
app.filter(new pinus.filters.time());
|
|
app.filter(new pinus.filters.timeout());
|
|
|
|
app.filter(globalFilter(app));
|
|
app.globalAfter((err: Error, routeRecord: RouteRecord, msg: any, session: FrontendOrBackendSession, resp: any, cb: HandlerCallback) => {
|
|
if (err) infologger.debug(err);
|
|
})
|
|
|
|
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);
|
|
});
|
|
}
|
|
|
|
// TODO: 所有环境打开监听模块和日志
|
|
app.configure(function () {
|
|
// enable the system monitor modules
|
|
app.enable('systemMonitor');
|
|
app.enable('rpcDebugLog');
|
|
});
|
|
|
|
if (app.isMaster()) {
|
|
// app.use(createRobotPlugin({scriptFile: __dirname + '/robot/robot.js'}));
|
|
|
|
|
|
|
|
app.event.on('add_servers', (server) => {
|
|
redisService.setConnectors(server);
|
|
})
|
|
app.event.on('replace_servers', (server) => {
|
|
redisService.setConnectors(server);
|
|
})
|
|
app.event.on('remove_servers', (server) => {
|
|
redisService.removeConnectors(server);
|
|
})
|
|
app.event.on('start_all', () => {
|
|
// 全部服务器启动完毕后初始化 redis 数据
|
|
redisService.checkConnectors();
|
|
});
|
|
}
|
|
|
|
// start app
|
|
app.start();
|