Lifecycle
Lifecycle Hooks
Lifecycle hooks can be implemented by overriding the following methods of actors.
_onInitialize()
Called only once when the actor is first created. This method returns the initial state of the actor (see state documentation).
If you need to call code when the actor is started (e.g. after restarting for upgrading code), see _onStart
.
_onStart()
This method is called any time the actor is started (e.g. after restarting, upgrading code, or crashing).
This is called after the actor has been initialized but before any connections are accepted.
Use this method to set up any resources or start any background tasks, such as setInterval
.
_onStateChange(newState)
Called whenever the actor's state changes. This is often used to broadcast state updates.
_onBeforeConnect(opts)
Called whenever a new client connects to the actor. Clients can pass parameters when connecting, accessible via opts.parameters
.
The returned value becomes the connection's initial state and can be accessed later via connection.state
.
Connections cannot interact with the actor until this method completes successfully. Throwing an error will abort the connection. This can be used for authentication - see Authentication for details.
_onConnect(connection)
Executed after the client has successfully connected.
Messages will not be processed for this actor until this method succeeds.
Errors thrown from this method will cause the client to disconnect.
_onDisconnect(connection)
Called when a client disconnects from the actor. Use this to clean up any connection-specific resources.
Destroying actors
Actors can be shut down gracefully with this._shutdown()
. Clients will be gracefully disconnected.
This action is permanent and cannot be reverted.
Actors can also be destroyed externally via the platform API with actors.destroy.
Full Example
interface State {
count: number;
}
interface ConnParams {
authToken: string;
}
interface ConnState {
userId: string;
}
export default class Counter extends Actor<State, ConnParams, ConnState> {
async _onInitialize(): Promise<State> {
// Initialize with a count of 0
return {
count: 0
};
}
async _onStart(): Promise<void> {
// Upgrade state if needed
console.log('Started');
}
async _onStateChange(newState: State): Promise<void> {
// Broadcast the new count to all connected clients
this._broadcast('countUpdated', {
count: newState.count
});
}
async _onBeforeConnect(opts: OnBeforeConnectOptions<Counter>): Promise<ConnState> {
// Validate auth token with your API and determine the user
const auth = await myValidateAuthToken(opts.parameters.authToken);
if (!auth) {
throw new Error('Invalid auth token');
}
// Return connection state that will be available as connection.state
return {
userId: auth.userId
};
}
async _onConnect(connection: Connection<Counter>): Promise<void> {
console.log(`User ${connection.state.userId} connected`);
}
async _onDisconnect(connection: Connection<Counter>): Promise<void> {
console.log(`User ${connection.state.userId} disconnected`);
}
// Example RPC method
async increment(rpc: Rpc<Counter>) {
this._state.count++;
}
}