From aa5dc07b864907c83db7f61225a82c59556834aa Mon Sep 17 00:00:00 2001 From: luying Date: Mon, 23 Nov 2020 16:29:21 +0800 Subject: [PATCH] =?UTF-8?q?redis=20=E6=8E=92=E8=A1=8C=E6=A6=9C=E5=88=86?= =?UTF-8?q?=E5=8C=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- game-server/app.ts | 2 +- .../battle/handler/normalBattleHandler.ts | 3 +- .../battle/handler/towerBattleHandler.ts | 14 +++-- .../servers/connector/handler/entryHandler.ts | 3 +- game-server/app/services/battleService.ts | 4 +- game-server/app/services/redisService.ts | 56 +++++++++++++++---- shared/db/Game.ts | 9 +++ shared/db/Role.ts | 4 +- 8 files changed, 72 insertions(+), 23 deletions(-) diff --git a/game-server/app.ts b/game-server/app.ts index 2627a1996..19063aa7e 100644 --- a/game-server/app.ts +++ b/game-server/app.ts @@ -55,7 +55,7 @@ mongoose.connect(mongoAddr, { useNewUrlParser: true, useUnifiedTopology: true }, } }); -redisService.initRank(); +redisService.initAllRank(); /** * Init app for client. */ diff --git a/game-server/app/servers/battle/handler/normalBattleHandler.ts b/game-server/app/servers/battle/handler/normalBattleHandler.ts index 278bdeb66..d734fd36d 100644 --- a/game-server/app/servers/battle/handler/normalBattleHandler.ts +++ b/game-server/app/servers/battle/handler/normalBattleHandler.ts @@ -155,6 +155,7 @@ export class NormalBattleHandler { let roleId = session.get('roleId'); let roleName = session.get('roleName'); let sid = session.get('sid'); + let serverId = session.get('serverId'); let warInfo = getWarById(battleId); if(!warInfo) { return resResult(STATUS.BATTLE_MISS_INFO); @@ -201,7 +202,7 @@ export class NormalBattleHandler { // 记录事件状态 await setBattleStatus(this.app, session, roleId, battleId, isSuccess, battleCode); } else if (warInfo.warType == WAR_TYPE.TOWER) { - let towerEndResult = await towerBattleEnd(channelService, sid, roleId, battleCode, battleId, isSuccess, heroes); + let towerEndResult = await towerBattleEnd(channelService, sid, roleId, serverId, battleCode, battleId, isSuccess, heroes); if(towerEndResult) { if(towerEndResult.status == -1) { return towerEndResult.resResult; diff --git a/game-server/app/servers/battle/handler/towerBattleHandler.ts b/game-server/app/servers/battle/handler/towerBattleHandler.ts index 3196a431e..5a9c995fc 100644 --- a/game-server/app/servers/battle/handler/towerBattleHandler.ts +++ b/game-server/app/servers/battle/handler/towerBattleHandler.ts @@ -11,7 +11,7 @@ import { decodeArrayStr, resResult, shouldRefresh, calculateNum, getRefTime, gen import { calcuHangUpReward, checkTaskConditions, checkHangUpSpdUpCnt, createCurTasks, treatTask, getRemainTime, getTasksReward, getTaskStatus, getDoingOrWaitingTasks } from '../../../services/battleService'; import { handleFixedReward, handleReward } from '../../../services/rewardService'; import { checkBattleHeroes } from '../../../services/normalBattleService'; -import { getRank, setRank } from '../../../services/redisService'; +import { getRank, setRank, initRank, existsRank } from '../../../services/redisService'; export default function(app: Application) { return new TowerBattleHandler(app); @@ -27,13 +27,14 @@ export class TowerBattleHandler { */ async getStatus(msg: {}, session: BackendSession) { let roleId = session.get('roleId'); + let serverId = session.get('serverId'); let { towerLv } = await RoleModel.findByRoleId(roleId); if (!towerLv) { towerLv = 1; let role = await RoleModel.towerLvUp(roleId); // 更新redis let { roleName, towerUpTime, lv, vLv } = role; - await setRank(REDIS_KEY.TOWER_RANK, roleId, towerLv, towerUpTime.getTime(), {roleName, lv, vLv, guildName:"", head: "zhaoyun"}); + await setRank(REDIS_KEY.TOWER_RANK, serverId, roleId, towerLv, towerUpTime.getTime(), {roleName, lv, vLv, guildName:"", head: "zhaoyun"}); } let towerRec = await TowerRecordModel.getRecordByLv(roleId, towerLv); @@ -105,7 +106,7 @@ export class TowerBattleHandler { const goods = await handleReward(roleId, roleName, timeReward); await HangUpRecordModel.updateRec(roleId, roleName, endLv, endTime, needReceiveGoods); - return resResult(STATUS.SUCCESS, { endTime, hangUpPassTime: Math.floor((deltaTime%HANG_UP_CONSTS.MAX_TIME)/1000), ...goods }); + return resResult(STATUS.SUCCESS, { endTime, hangUpPassTime: Math.floor((deltaTime%HANG_UP_CONSTS.UNIT_TIME)/1000), ...goods }); } async hangUpSpeedUp(msg: {speedUpCnt: number}, session: BackendSession) { @@ -303,12 +304,15 @@ export class TowerBattleHandler { return resResult(STATUS.SUCCESS, { curTasks: treatTask(curTasks, curTime), goods, refRemainTime, nextCostGold: costGold }); } - async getTowerRank(msg: {}, session: BackendSession) { let roleId = session.get('roleId'); let roleName = session.get('roleName'); + let serverId = session.get('serverId') - let {ranks, myRank} = await getRank(REDIS_KEY.TOWER_RANK, roleId); + const hasTowerRank = await existsRank(REDIS_KEY.TOWER_RANK, serverId); + if(!hasTowerRank) await initRank(serverId); + + let {ranks, myRank} = await getRank(REDIS_KEY.TOWER_RANK, serverId, roleId); if(!myRank) { let role = await RoleModel.findByRoleId(roleId); let {towerLv, lv, vLv} = role; diff --git a/game-server/app/servers/connector/handler/entryHandler.ts b/game-server/app/servers/connector/handler/entryHandler.ts index fc75b2c3e..e501fa1ec 100644 --- a/game-server/app/servers/connector/handler/entryHandler.ts +++ b/game-server/app/servers/connector/handler/entryHandler.ts @@ -27,7 +27,6 @@ export class EntryHandler { * @param {Object} session current session object */ async enter(msg: { token: string, serverId: number }, session: FrontendSession) { - let self = this; let serverId = msg.serverId; let sessionService = self.app.get('sessionService'); @@ -53,10 +52,12 @@ export class EntryHandler { session.set('roleName', role.roleName); session.set('eventStatus', role.eventStatus); session.set('sid', self.app.get('serverId')); + session.set('serverId', role.serverId); session.push('sid', () => {}); session.push('roleId', () => {}); session.push('roleName', () => {}); session.push('eventStatus', () => {}); + session.push('serverId', () => {}); // session.push('rid', function (err) { // if (err) { // console.error('set rid for session service failed! error is : %j', err.stack); diff --git a/game-server/app/services/battleService.ts b/game-server/app/services/battleService.ts index 9ed475cbe..4cec3b752 100644 --- a/game-server/app/services/battleService.ts +++ b/game-server/app/services/battleService.ts @@ -47,7 +47,7 @@ export async function checkTowerWar(roleId: string, battleId: number, heroes: Ar }}; } -export async function towerBattleEnd(channelService: ChannelService, sid: string, roleId: string, battleCode: string, battleId: number, succeed: boolean, heroes: Array) { +export async function towerBattleEnd(channelService: ChannelService, sid: string, roleId: string, serverId: number, battleCode: string, battleId: number, succeed: boolean, heroes: Array) { if (succeed) { let battleRec = await BattleRecordModel.getBattleRecordByCode(battleCode); if (battleRec.battleId != battleId) { @@ -73,7 +73,7 @@ export async function towerBattleEnd(channelService: ChannelService, sid: string let role = await RoleModel.towerLvUp(roleId); // 更新redis let { roleName, towerLv, towerUpTime, lv, vLv } = role; - await setRank(REDIS_KEY.TOWER_RANK, roleId, towerLv, towerUpTime.getTime(), {roleName, lv, vLv, guildName:"", head: "zhaoyun"}); + await setRank(REDIS_KEY.TOWER_RANK, serverId, roleId, towerLv, towerUpTime.getTime(), {roleName, lv, vLv, guildName:"", head: "zhaoyun"}); const nextTowerInfo = getTowerDataByLv(towerLv + 1); if (nextTowerInfo) { diff --git a/game-server/app/services/redisService.ts b/game-server/app/services/redisService.ts index db819f0ed..43d3e5882 100644 --- a/game-server/app/services/redisService.ts +++ b/game-server/app/services/redisService.ts @@ -1,6 +1,8 @@ import { RoleModel } from "../db/Role"; import * as redis from 'redis'; import {REDIS_KEY} from '../consts/consts' +import { GameModel } from "../db/Game"; +import { exists } from "fs"; let redisArr = 'r-8vb4i2kgl91886fkxd.redis.zhangbei.rds.aliyuncs.com'; if(process.env.NODE_ENV == 'local') { @@ -20,16 +22,38 @@ client.set('hello', 'redis', redis.print); /** * 在服务重新启动时,将信息存入redis */ -export async function initRank() { - await redisDel(REDIS_KEY.TOWER_RANK); // 清空天梯排行榜(ZSet) - await redisDel(REDIS_KEY.USER_INFO); // 清空用户缓存信息 - let ranks = await RoleModel.getRank('tower', ['roleId', 'roleName', 'towerLv', 'lv', 'vLv']); +export async function initAllRank() { + const serverList = await GameModel.getAllServerList(); + await redisDel(REDIS_KEY.USER_INFO); + for(let {id} of serverList) { + await redisDel(getKeyName(REDIS_KEY.TOWER_RANK, id)); + await initRank(id); + } +} + +export async function initRank(serverId: number) { + console.log('*****', 'initRank') + await redisExpire(getKeyName(REDIS_KEY.TOWER_RANK, serverId), 30 * 24 * 60 * 60); + await redisExpire(REDIS_KEY.USER_INFO, 30 * 24 * 60 * 60); + + let ranks = await RoleModel.getRank('tower', serverId, ['roleId', 'roleName', 'towerLv', 'lv', 'vLv']); for(let {towerLv, roleId, roleName, lv, vLv, towerUpTime} of ranks) { - await redisZadd(REDIS_KEY.TOWER_RANK, encodeScoreWithTime(towerLv, towerUpTime?towerUpTime.getTime():0), roleId); + console.log(roleId); + await redisZadd(getKeyName(REDIS_KEY.TOWER_RANK, serverId), encodeScoreWithTime(towerLv, towerUpTime?towerUpTime.getTime():0), roleId); await redisUserInfoAdd(roleId, {roleName, lv, vLv, guildName:"", head: "zhaoyun"}); } } +// 排行榜是否存在 +export async function existsRank(key: string, serverId: number) { + const result = await redisExists(getKeyName(key, serverId)); + return result; +} + +export function getKeyName(key: string, serverId: number) { + return `${key}:${serverId.toString()}`; +} + // 更新玩家信息 export async function redisUserInfoUpdate(roleId: string, arr: Array<{field: string, value:(string|number)}>) { let params = await redisHget(REDIS_KEY.USER_INFO, roleId); @@ -49,12 +73,12 @@ export async function redisUserInfoAdd(roleId: string, params: {roleName: string } // 更新排行榜 -export async function setRank(key: string, roleId: string, score: number, timestamp: number, params: {roleName: string, lv: number, vLv: number, guildName: string, head: string}) { +export async function setRank(key: string, serverId: number, roleId: string, score: number, timestamp: number, params: {roleName: string, lv: number, vLv: number, guildName: string, head: string}) { // 更新分数 const _score = encodeScoreWithTime(score, timestamp); - await redisZadd(key, _score, roleId); + await redisZadd(getKeyName(key, serverId), _score, roleId); // 移除100名以外 - await redisZremRangeByRank(key, 0, 100); + await redisZremRangeByRank(getKeyName(key, serverId), 100, 10000); // 如果没有信息,更新玩家信息 const hasCurUser = await redisHexists(REDIS_KEY.USER_INFO, roleId); if(!hasCurUser) { @@ -64,15 +88,15 @@ export async function setRank(key: string, roleId: string, score: number, timest } // 获取排行榜 -export async function getRank(key: string, roleId: string) { +export async function getRank(key: string, serverId: number, roleId: string) { let ranks = [], myRank = null; - const rankFromDb = await redisZrevrangeByScore(key, '+inf', '-inf', true, 100); + const rankFromDb = await redisZrevrangeByScore(getKeyName(key, serverId), '+inf', '-inf', true, 100); for(let ii = 0; ii < rankFromDb.length; ii+=2) { const _roleId = rankFromDb[ii]; const _score = decodeScoreWithTime(rankFromDb[ii + 1]); const userInfo = await redisHget(REDIS_KEY.USER_INFO, _roleId); const _userInfo = JSON.parse(userInfo); - const tmp = {..._userInfo, roleId: _roleId, num: _score, rank: ii%2+1} + const tmp = {..._userInfo, roleId: _roleId, num: _score, rank: Math.floor(ii/2)+1} ranks.push(tmp); if(roleId == _roleId) myRank = tmp; } @@ -99,11 +123,21 @@ function decodeScoreWithTime(num: string): number { //// key +// key 是否存在。 +export async function redisExists(key: string) { + return await createPromise('exists', [key]); +} + // 在 key 存在时删除 key。 export async function redisDel(key: string) { return await createPromise('del', [key]); } +// 设置过期时间 +export async function redisExpire(key: string, seconds: number) { + return await createPromise('expire', [key, seconds]); +} + //// 有序集合 // 返回有序集中指定分数区间内的成员,分数从高到低排序 diff --git a/shared/db/Game.ts b/shared/db/Game.ts index f419327da..6e39d0412 100644 --- a/shared/db/Game.ts +++ b/shared/db/Game.ts @@ -55,6 +55,15 @@ export default class Game extends BaseModel { @prop({ required: true }) versionCode: number; + public static async getAllServerList() { + let game = await GameModel.findOne().lean(); + if(game) { + return game.serverList; + } else { + return [] + } + } + public static async getServerListByType(serverType: string) { let game = await GameModel.findOne().lean(); if (!game) { diff --git a/shared/db/Role.ts b/shared/db/Role.ts index c985ef8af..d68ff5c04 100644 --- a/shared/db/Role.ts +++ b/shared/db/Role.ts @@ -339,13 +339,13 @@ export default class Role extends BaseModel { } // 获取排行榜 - public static async getRank(type: string, fields: Array, page = 1, limit = 100, lean = true) { + public static async getRank(type: string, serverId: number, fields: Array, page = 1, limit = 100, lean = true) { let sortBy = {}; if(type == 'tower') { sortBy['towerLv'] = -1; sortBy['towerUpTime'] = 1; } - const ranks = await RoleModel.find().select(fields.join(' ')).sort(sortBy).limit(limit).skip((page - 1) * limit).lean(lean); + const ranks = await RoleModel.find({serverId}).select(fields.join(' ')).sort(sortBy).limit(limit).skip((page - 1) * limit).lean(lean); return ranks; }