增加房间的自我销毁机制

This commit is contained in:
zhl 2021-04-30 16:36:31 +08:00
parent f785915b7a
commit 49400c858f
3 changed files with 211 additions and 3 deletions

View File

@ -0,0 +1,8 @@
export class ClockNameConst {
/**
*
* @type {string}
*/
public static readonly ROOM_LIFE_CLOCK = 'room_life_clock'
}

53
src/global.d.ts vendored
View File

@ -32,6 +32,59 @@ declare module 'colyseus' {
* @param data
*/
bUserReconnect(data?: any): void;
// >>>>>>>>> End of extend send message <<<<<<<<<<<<<
// >>>>>>>>> Begin of extend schedule functions <<<<<<<<<<<<<
/**
*
* @param millisecond
* @param handler
* @param name
*/
beginSchedule(millisecond: number, handler: Function, name: string): void;
/**
* active
* @param {string} name
* @return {boolean}
*/
scheduleActive(name: string): boolean;
/**
*
*/
pauseAllSchedule(): string[];
/**
*
*/
resumeAllSchedule(): string[];
/**
*
*/
stopSchedule(name: string): number;
/**
*
*/
pauseSchedule(name: string): number;
/**
*
*/
resumeSchedule(name: string): number;
/**
* n秒
* @param name
* @param millisecond
* @param reason
*/
addScheduleTime(millisecond: number, reason?: string, name?: string): void;
// >>>>>>>>> End of extend schedule functions <<<<<<<<<<<<<
}
}

View File

@ -1,17 +1,20 @@
import { Client, Room } from 'colyseus'
import { Dispatcher } from '@colyseus/command'
import { IncomingMessage } from 'http'
import { debugRoom, msgLog } from '../common/Debug'
import { debugRoom, error, msgLog } from '../common/Debug'
import { OnJoinCommand } from './commands/OnJoinCommand'
import { Player } from './schema/Player'
import { BeginGameCommand } from './commands/BeginGameCommand'
import { PuzzleGameState } from './schema/PuzzleGameState'
import { EndGameCommand } from './commands/EndGameCommand'
import { GameStateConst } from '../constants/GameStateConst'
import { Delayed } from '@gamestdio/timer/lib/Delayed'
import { ClockNameConst } from '../constants/ClockNameConst'
export class PuzzleMathRoom extends Room {
dispatcher = new Dispatcher(this)
// 用于游戏过程中各种计时器, 使用该计时器的前提是, 只针对当前操作玩家
gameClock: Map<string, Delayed> = new Map()
async onAuth(client: Client, options: any, request: IncomingMessage) {
debugRoom(options)
@ -19,13 +22,27 @@ export class PuzzleMathRoom extends Room {
return true
}
onCreate(options: any) {
this.autoDispose = false
let cs = new PuzzleGameState()
this.setState(cs)
this.clock.start()
this.onMessage('*', (client, type, message) => {
msgLog(client.sessionId, 'sent', type, JSON.stringify(message))
})
/**
* , maxTime, , maxTime来定时销毁
* , game svr端会在业务逻辑处理完后, ,
* , game svr程序出错而出现僵尸房间的情况
*/
if ( options.maxTime ) {
this.autoDispose = false
let self = this
this.beginSchedule(options.maxTime * 1000, async function (){
await self.disconnect()
}.bind(this), ClockNameConst.ROOM_LIFE_CLOCK)
}
}
onJoin(client: Client, options: any) {
@ -59,6 +76,10 @@ export class PuzzleMathRoom extends Room {
onDispose() {
this.dispatcher.stop()
for (let [, clock] of this.gameClock) {
clock.clear()
}
this.gameClock.clear()
}
/**
@ -134,4 +155,130 @@ export class PuzzleMathRoom extends Room {
updateRound(round: number) {
this.state.round = round
}
/**
*
* @param millisecond
* @param handler
* @param name
*/
beginSchedule(millisecond: number, handler: Function, name: string): void {
debugRoom(`begin schedule: `, name, millisecond / 1000)
if (this.gameClock.has(name) && this.gameClock.get(name)?.active) {
error(`当前已存在进行中的gameClock: ${ name }`)
this.gameClock.get(name).clear()
this.gameClock.delete(name)
}
let self = this
let timeOverFun = function () {
handler && handler()
}
this.gameClock.set(name, this.clock.setTimeout(timeOverFun, millisecond, name))
}
/**
*
*/
stopSchedule(name: string): number {
debugRoom(`manual stop schedule: ${ name }`)
if (!this.gameClock.has(name)) {
return -1
}
let clock = this.gameClock.get(name)
if (!clock.active) {
this.gameClock.delete(name)
return -1
}
let time = clock.elapsedTime
clock.clear()
this.gameClock.delete(name)
return time
}
scheduleActive(name: string): boolean {
return this.gameClock.has(name) && this.gameClock.get(name).active
}
pauseAllSchedule() {
let result: string[] = []
for (let [name, clock] of this.gameClock) {
if (clock.active) {
result.push(name)
clock.pause()
}
}
return result
}
resumeAllSchedule(): string[] {
let result: string[] = []
for (let [name, clock] of this.gameClock) {
if (clock.active && clock.paused) {
result.push(name)
clock.resume()
}
}
return result
}
/**
* ,
* @param {string} name
* @return {number}
*/
pauseSchedule(name: string) {
if (!this.gameClock.has(name)) {
return -1
}
let clock = this.gameClock.get(name)
if (!clock.active) {
return -1
}
clock.pause()
return clock.elapsedTime
}
/**
* ,
* @param {string} name
* @return {number}
*/
resumeSchedule(name: string) {
if (!this.gameClock.has(name)) {
return -1
}
let clock = this.gameClock.get(name)
if (!clock.active) {
return -1
}
clock.resume()
return clock.time - clock.elapsedTime
}
/**
* n秒
* @param name
* @param millisecond
* @param reason
*/
addScheduleTime(millisecond: number, reason?: string, name?: string): void {
let current
let currentName = name
if (!name) {
for (let [id, clock] of this.gameClock) {
if (clock.active) {
current = clock
currentName = id
break
}
}
} else {
if (this.gameClock.has(name)) {
current = this.gameClock.get(name)
}
}
debugRoom(`add schedule for ${ currentName }, time: ${ millisecond / 1000 }, reason: ${ reason }`)
if (current) {
current.time += millisecond
debugRoom(`schedule for ${ name } remain: ${ (current.time - current.elapsedTime) / 1000 }`)
}
}
}