系统:停服维护逻辑

This commit is contained in:
luying
2021-07-15 14:40:26 +08:00
parent 352aecfb56
commit 0028c9b992
26 changed files with 348 additions and 50 deletions
+2 -2
View File
@@ -16,7 +16,7 @@ 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');
var globalFilter = require('./app/servers/connector/filter/global');
import { connectRedis } from './config/redis';
import * as timeTaskService from './app/services/timeTaskService';
import * as redlockCacheService from './app/services/redlockCacheService';
@@ -198,7 +198,7 @@ app.configure(ALL_ENVS, function () {
app.filter(new pinus.filters.time());
app.filter(new pinus.filters.timeout());
app.filter(checkEventFilter(app));
app.filter(globalFilter(app));
// RPC 启用TCP协议
app.set('proxyConfig', {
@@ -1,26 +0,0 @@
import {Application, RouteRecord, FrontendOrBackendSession, HandlerCallback} from "pinus";
import {checkEvent} from '../../../services/eventSercive';
import { refresh } from '../../../services/refreshService';
module.exports = function(app: Application) {
return new Filter(app);
}
var Filter = function(this: any, app: Application) {
this.app = app;
};
Filter.prototype.before = function (routeRecord: RouteRecord, msg: any, session: FrontendOrBackendSession, next: HandlerCallback) {
next(null);
};
Filter.prototype.after = function (err: Error, routeRecord: RouteRecord, msg: any, session: FrontendOrBackendSession, resp: any, next: HandlerCallback) {
//刷新
refresh(session);
return checkEvent(session).then(()=>{
next(err);
}).catch(e => {
console.error(e);
next(err);
}); // 奇遇本检查
};
@@ -239,4 +239,17 @@ export class ChatRemote {
if (!channel) return;
channel.pushMessage(path, resResult(STATUS.SUCCESS, data));
}
/**
* @description 全服推送维护
* @param serverId
*/
public async sendServerMaintenance(serverId: number) {
let roomId = groupRoomId(CHANNEL_PREFIX.WORLD, serverId);
let channel = this.channelService.getChannel(roomId, false);
if (!channel) return { result: false, serverId };
channel.pushMessage('onServerMaintenance', resResult(STATUS.SERVER_MAINTENANCE));
return { result: true, serverId };
}
}
@@ -0,0 +1,45 @@
import {Application, RouteRecord, FrontendOrBackendSession, HandlerCallback, pinus} from "pinus";
import { checkEvent } from '../../../services/eventSercive';
import { refresh } from '../../../services/refreshService';
import { getWorldChannelSid } from "../../../services/chatService";
import { resResult, checkWhiteListWithUid } from "../../../pubUtils/util";
import { STATUS } from "../../../consts";
import { UserModel } from "../../../db/User";
module.exports = function(app: Application) {
return new Filter(app);
}
var Filter = function(this: any, app: Application) {
this.app = app;
};
Filter.prototype.before = async function (routeRecord: RouteRecord, msg: any, session: FrontendOrBackendSession, next: HandlerCallback) {
const serverId: number = session.get('serverId');
const sid: string = session.get('sid');
const roleId: string = session.get('roleId');
const uid: number = session.get('userid');
let connectorServers = pinus.app.getServersByType('connector');
let { id } = connectorServers[0];
let maintenServers = await pinus.app.rpc.connector.connectorRemote.getServerMainten.toServer(id);
if(maintenServers.indexOf(serverId) != -1) { // 该服务器维护
let isWhiteList = await checkWhiteListWithUid(uid);
if(isWhiteList) next(null);
pinus.app.get('channelService').pushMessageByUids('onServerMaintenance', resResult(STATUS.SERVER_MAINTENANCE), [{ uid: roleId, sid }]);
next(new Error(), resResult(STATUS.SERVER_MAINTENANCE));
}
next(null);
};
Filter.prototype.after = function (err: Error, routeRecord: RouteRecord, msg: any, session: FrontendOrBackendSession, resp: any, next: HandlerCallback) {
//刷新
refresh(session);
return checkEvent(session).then(()=>{
next(err);
}).catch(e => {
console.error(e);
next(err);
}); // 奇遇本检查
};
@@ -118,6 +118,7 @@ export class EntryHandler {
async addSession(role: RoleType, session: FrontendSession) {
const self = this;
await session.abind(role.roleId);
session.set('userid', role.userInfo.uid);
session.set('uid', role.roleId);
session.set('roleId', role.roleId);
let updatedMailAt = role.updatedMailAt ? role.updatedMailAt : 0;
@@ -128,6 +129,7 @@ export class EntryHandler {
session.set('serverId', role.serverId);
session.set('funcs', role.funcs || []);
session.set('guildCode', role.guildCode);
session.push('userid', () => { });
session.push('sid', () => { });
session.push('roleId', () => { });
session.push('roleName', () => { });
@@ -13,6 +13,7 @@ export class ConnectorRemote {
this.channelService = app.get('channelService');
}
private channelService: ChannelService;
private maintenServers: number[] = []; // 维护中的服务器
public async remoteLogin(uid: string) {
let sessionService = this.app.get('sessionService');
@@ -22,7 +23,7 @@ export class ConnectorRemote {
let roleId = session.get('roleId');
let sid = session.get('sid');
let uids = [{uid: roleId, sid}];
this.channelService.pushMessageByUids('onRemoteLogin', resResult(STATUS.LOGIN_ERR ), uids);
this.channelService.pushMessageByUids('onRemoteLogin', resResult(STATUS.SERVER_MAINTENANCE ), uids);
});
}
await sessionService.akick(uid);
@@ -42,4 +43,12 @@ export class ConnectorRemote {
public async reloadResources() {
reloadResources();
}
public setServerMainten(maintenServers: number[]) {
return this.maintenServers = maintenServers;
}
public getServerMainten() {
return this.maintenServers;
}
}
@@ -12,6 +12,8 @@ import { SendMailFun } from '../../../services/mailService';
import { GM_MAIL_TYPE } from '../../../consts';
import { RewardInter } from '../../../pubUtils/interface';
import { MarqueeModel } from '../../../db/Marquee';
import { ServerlistModel } from '../../../db/Serverlist';
import { getWorldChannelSid } from '../../../services/chatService';
export default function(app: Application) {
return new GmHandler(app);
}
@@ -183,4 +185,24 @@ export class GmHandler {
}
return resResult(STATUS.SUCCESS);
}
async sendMaintenance(msg: { serverType: string }, session: BackendSession) {
const { serverType } = msg;
let allServers = await ServerlistModel.findByServerType(serverType);
let results = [];
for(let { serverId } of allServers) {
let chatSid = await getWorldChannelSid(serverId);
let result = await this.app.rpc.chat.chatRemote.sendServerMaintenance.toServer(chatSid, serverId);
results.push(result);
}
return resResult(STATUS.SUCCESS, results);
}
async setMaintenance() {
let connectorServers = pinus.app.getServersByType('connector');
for(let { id } of connectorServers) {
pinus.app.rpc.connector.connectorRemote.setServerMainten.toServer(id, [1]);
}
return resResult(STATUS.SUCCESS);
}
}
@@ -66,7 +66,7 @@ export class RoleHandler {
await checkPvp(role);
return resResult(STATUS.SUCCESS, {
roleId, roleName, heroes
roleId, roleName, ...heroes
})
}
@@ -3,7 +3,7 @@ import { resetPvpSeasonTime, setPvpDefResult, guildActivityStart, gateActivityEn
import PvpDefenseType from '../../../db/PvpDefense';
import { DicGuildActivity } from '../../../pubUtils/dictionary/DicGuildActivity';
import { reloadResources } from '../../../pubUtils/data';
import { setMarquee, cancelMarquee } from '../../../services/marqueeService';
import { setMarquee, cancelMarquee } from '../../../services/gmService';
export default function (app: Application) {
return new SystimerRemote(app);
@@ -1,10 +1,17 @@
import { MarqueeType, MarqueeModel } from "../db/Marquee";
import { MARQUEE_TYPE, STATUS } from "../consts";
import { MARQUEE_TYPE, STATUS, SERVER_STATUS } from "../consts";
import { scheduleJob, scheduledJobs, Job } from 'node-schedule';
import { createMarqueeMsg as sysCreateMarqueeMsg, pushMarqueeMsg as sysPushMarqueeMsg } from './sysChatService';
import { GroupMessageType } from "../db/GroupMessage";
import { resResult } from "../pubUtils/util";
import { MaintenanceModel, MaintenanceType } from '../db/Maintenance';
import { pinus } from "pinus";
import { getWorldChannelSid } from "./chatChannelService";
import { ServerlistModel } from "../db/Serverlist";
import { NoticeModel, NoticeType } from "../db/Notice";
// —————————————— 跑马灯 —————————————— //
// 初始
export async function initMarquee() {
const marquees = await MarqueeModel.findEffectiveMarque();
for(let marquee of marquees) {
@@ -24,6 +31,9 @@ export async function setMarquee(code: string) {
}
async function generateMarqueeSchedule(marquee: MarqueeType) {
let setSecondsMarquee = scheduledJobs[`setSeconds${marquee.code}`];
if(setSecondsMarquee) return false; // 已经在运行中了
if(marquee.type != MARQUEE_TYPE.SCHEDULE) return false;
if(marquee.startTime.getTime() >= marquee.endTime.getTime()) return false;
if(marquee.endTime.getTime() < Date.now()) return false;
@@ -88,4 +98,44 @@ export async function cancelMarquee(code: string) {
if(endMarquee) endMarquee.cancel();
await MarqueeModel.updateData(code, { isRunning: false });
return true
}
// —————————————— 停服维护 —————————————— //
// 维护信息
export async function initMaintenance() {
const maintenance = await MaintenanceModel.findOpenMaintenance();
if(maintenance) {
let { startTime, marquee } = maintenance;
if(marquee) await generateMarqueeSchedule(<MarqueeType>marquee);
if(Date.now() > startTime.getTime()) {
await startMaintenance(maintenance);
} else {
let startJob = scheduleJob(`startMainten${maintenance.code}`, startTime.getTime(), async () => {
await startMaintenance(maintenance, startJob);
});
}
}
}
async function startMaintenance(maintenance: MaintenanceType, startJob?: Job) {
// 向全服发送
let { serverIds, notice } = maintenance;
for(let serverId of serverIds) {
let chatSid = await getWorldChannelSid(serverId);
await pinus.app.rpc.chat.chatRemote.sendServerMaintenance.toServer(chatSid, serverId);
}
// 更新serverlist上的status
await ServerlistModel.updateByServerIds(serverIds, { serverStatus: SERVER_STATUS.MAINTENANCE });
// 更新notice的isEnable
if(notice) {
await NoticeModel.updateNotice((<NoticeType>notice).id, { isEnable: true });
}
// 更新connectorRemote里面的
let connectorServers = pinus.app.getServersByType('connector');
for(let { id } of connectorServers) {
pinus.app.rpc.connector.connectorRemote.setServerMainten.toServer(id, serverIds);
}
if(startJob) startJob.cancel();
}
+5 -2
View File
@@ -1,5 +1,5 @@
import { scheduleJob, Job } from 'node-schedule';
import { scheduleJob, Job, scheduledJobs } from 'node-schedule';
import { SystemConfigModel } from '../db/SystemConfig';
import PvpDefenseType,{ PvpDefenseModel } from '../db/PvpDefense';
import { PVP } from '../pubUtils/dicParam';
@@ -27,7 +27,7 @@ import { dispatch } from '../util/dispatcher';
import { Rank } from './rankService';
import { checkTask } from './taskService';
import { everydayRefresh } from './connectorService';
import { initMarquee } from './marqueeService';
import { initMarquee, initMaintenance } from './gmService';
const PER_SECOND = 1 * 1000;
const PER_DAY = 24 * 60 * 60;
@@ -87,6 +87,9 @@ export async function init() {
// 跑马灯
await initMarquee();
// 维护信息
await initMaintenance();
}
function setPvpSeasonSchdule() {