Room Lifecycle Events
These hooks are called automatically, in the order a client moves through the
room: created, authenticated, joined, dropped, reconnected, left, disposed.
async/await
is supported in all of them.
The room’s lifecycle events are called automatically. async/await is supported in all of them.
import { Room, Client, AuthContext } from "colyseus";
export class MyRoom extends Room {
// (optional) Validate client auth token before joining/creating the room
onAuth (client: Client, options: any, context: AuthContext) { }
// When room is initialized
onCreate (options: any) { }
// When the client successfully joins the room
onJoin (client: Client, options: any, auth: any) { }
// When a client disconnects unexpectedly (use allowReconnection here)
onDrop (client: Client, code?: number) { }
// When a client successfully reconnects
onReconnect (client: Client) { }
// When a client effectively leaves the room
onLeave (client: Client, code?: number) { }
// Cleanup callback, called after there are no more clients in the room. (see `autoDispose`)
onDispose () { }
}On Create
Called once, when the room is created by the matchmaker. options is the merged values specified on defineRoom() with the options provided from the SDK at .joinOrCreate() or .join().
onCreate (options) {
/**
* This is a good place to initialize your room state.
*/
}The server may overwrite options in defineRoom() for authority over client-provided options:
// (backend)
const server = defineServer({
rooms: {
my_room: defineRoom(MyRoom, { map: "cs_assault" })
}
})On this example, the map option is "cs_assault" during onCreate(), and "de_dust2" during onJoin().
On Auth
The onAuth method is called before onJoin, and it is responsible for validating the client’s request to join a room.
async onAuth (client, options, context) {
/**
* This is a good place to validate the client's auth token.
*/
}Arguments
client: A reference to the client that is trying to join the room.options: Options provided by the frontend SDK.context: The request context, containing:.token- the authentication token sent by the client..headers- the headers sent by the client..ip- the IP address of the client.
See Authentication for more details.
On Join
Triggered when a client successfully joins the room, after a successful onAuth.
Parameters:
client: A reference to the client that joined the room.options: Options provided by the Client SDK. (Merged with default values provided by Server#define())auth: (optional) auth data returned byonAuthmethod.
async onJoin (client, options, auth?) {
/**
* This is a good place to add the client to the state.
*/
}See Client SDK on .joinOrCreate() and .join().
On Drop
New in 0.17. See Automatic Reconnection for more details.
Triggered when a client disconnects unexpectedly (without consent). This hook is the recommended place to use allowReconnection().
Parameters:
client: The client that was dropped from the room.code: (optional) The close code of the leave event.
async onDrop (client, code) {
await this.allowReconnection(client, 20);
}If onDrop is not defined, onLeave will be called for both consented and non-consented disconnections.
On Reconnect
New in 0.17. See Automatic Reconnection for more details.
Triggered when a client successfully reconnects to the room after calling allowReconnection().
Parameters:
client: The client that reconnected to the room.
onReconnect (client) {
/**
* Client has reconnected successfully.
*/
console.log(client.sessionId, "reconnected!");
}On Leave
Triggered when a client effectively leaves the room.
- If
onDropis defined:onLeaveis called for consented disconnections (client called.leave()), and also after a drop once reconnection fails, times out, or was not allowed. - If
onDropis not defined:onLeaveis called for both consented and non-consented disconnections.
Parameters:
client: The client that left the room.code: (optional) The close code of the leave event.
async onLeave (client, code) {
/**
* This is a good place to remove the client from the state.
*/
}You may define this function as async:
onLeave(client, code) {
if (this.state.players.has(client.sessionId)) {
this.state.players.delete(client.sessionId);
}
}At Graceful Shutdown, onLeave is called with code = CloseCode.SERVER_SHUTDOWN for all clients.
On Dispose
The onDispose() method is called before the room is destroyed, which happens when:
- there are no more clients left in the room, and
autoDisposeis set totrue(default) - you manually call
.disconnect().
async onDispose() {
/**
* This is a good place to perform cleanup tasks.
*/
}You may define async onDispose() an asynchronous method in order to persist some data in the database. In fact, this is a great place to persist player’s data in the database after a game match ends.
At Graceful Shutdown, onDispose is called for all rooms.
On Unhandled Exception
Opt-in to catch unhandled exceptions in your room. This method is called when an unhandled exception occurs in any of the lifecycle methods.
onUncaughtException (err: Error, methodName: string) {
console.error("An error occurred in", methodName, ":", err);
err.cause // original unhandled error
err.message // original error message
}See Exception Handling for more details.
On Before Patch
The onBeforePatch lifecycle hook is triggered before state synchronization, at patch rate frequency. (see patchRate)
onBeforePatch(state) {
/*
* Here you can mutate something in the state just before it is encoded &
* synchronized with all clients
*/
}On Cache Room (devMode)
An optional hook to cache external data when devMode is enabled.
(See restoring data outside the room’s state)
export class MyRoom extends Room {
// ...
onCacheRoom() {
return { foo: "bar" };
}
}On Restore Room (devMode)
An optional hook to reprocess/restore data which was returned and stored from the previous hook onCacheRoom when Development Mode is enabled.
export class MyRoom extends Room {
// ...
onRestoreRoom(cachedData: any): void {
console.log("ROOM HAS BEEN RESTORED!", cachedData);
this.state.players.forEach(player => {
player.method(cachedData["foo"]);
});
}
}On Before Shutdown
The onBeforeShutdown lifecycle hook is called as part of the Graceful Shutdown process. The process will only truly shutdown after all rooms have been disposed.
By default, the room will disconnect all clients and dispose itself immediately.
You may customize how the room should behave during the shutdown process:
onBeforeShutdown() {
//
// Notify users that process is shutting down, they may need to save their progress and join a new room
//
this.broadcast("going-down", "Server is shutting down. Please save your progress and join a new room.");
//
// Disconnect all clients after 5 minutes
//
this.clock.setTimeout(() => this.disconnect(), 5 * 60 * 1000);
}See graceful shutdown for more details.