Implementation:Microsoft Playwright Dispatcher
| Knowledge Sources | |
|---|---|
| Domains | RPC Protocol, Server Infrastructure |
| Last Updated | 2026-02-12 00:00 GMT |
Overview
Concrete tool for the base RPC dispatcher infrastructure provided by the Playwright library.
Description
The `Dispatcher` class is the foundation of Playwright's server-side RPC system. It extends `EventEmitter` and serves as the base class for all type-specific dispatchers (Page, BrowserContext, Frame, etc.). Each dispatcher wraps an `SdkObject` and registers it with a `DispatcherConnection` using a GUID. The class manages parent-child relationships between dispatchers, garbage collection of stale dispatchers based on configurable bucket limits, event dispatch to clients via `_dispatchEvent`, and progress controller tracking for cancellable operations. The `DispatcherConnection` class manages the full message lifecycle: receiving client messages, validating parameters, invoking dispatcher methods with metadata tracking, serializing results, and sending responses back. It also handles object lifecycle via `__create__` and `__dispose__` messages.
Usage
Use this class as the base for all server-side RPC dispatchers. Extend it to create type-specific dispatchers that expose server objects to remote clients through the Playwright protocol.
Code Reference
Source Location
- Repository: Microsoft_Playwright
- File: packages/playwright-core/src/server/dispatchers/dispatcher.ts
Signature
export class Dispatcher<Type extends SdkObject, ChannelType, ParentScopeType extends DispatcherScope> extends EventEmitter implements channels.Channel {
readonly connection: DispatcherConnection;
readonly _guid: string;
readonly _type: string;
readonly _gcBucket: string;
_object: Type;
constructor(parent: ParentScopeType | DispatcherConnection, object: Type, type: string, initializer: channels.InitializerTraits<ChannelType>, gcBucket?: string);
protected _dispatchEvent<T extends keyof channels.EventsTraits<ChannelType>>(method: T, params?: channels.EventsTraits<ChannelType>[T]): void;
_dispose(reason?: string): void;
addObjectListener(eventName: string | symbol, handler: (...args: any[]) => void): void;
}
export class DispatcherConnection {
constructor(isLocal: boolean);
sendMessageToClient(guid: string, type: string, method: string, params: any, sdkObject?: SdkObject): void;
onmessage(message: object): void;
}
Import
import { Dispatcher, DispatcherConnection } from '../server/dispatchers/dispatcher';
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| parent | ParentScopeType or DispatcherConnection | Yes | Parent scope or connection for hierarchy registration |
| object | Type (extends SdkObject) | Yes | Server-side object to wrap and expose |
| type | string | Yes | Type name for protocol identification |
| initializer | channels.InitializerTraits<ChannelType> | Yes | Initial state sent to client on creation |
| gcBucket | string | No | Garbage collection bucket name for memory management |
Outputs
| Name | Type | Description |
|---|---|---|
| __create__ message | object | Sent to client when dispatcher is registered |
| __dispose__ message | object | Sent to client when dispatcher is disposed |
| event messages | object | Events dispatched to client via _dispatchEvent |
| method results | object | Return values from dispatched method calls |
Usage Examples
// Define a custom dispatcher
class MyDispatcher extends Dispatcher<MyObject, channels.MyChannel, ParentDispatcher> {
constructor(scope: ParentDispatcher, obj: MyObject) {
super(scope, obj, 'MyObject', { name: obj.name });
this.addObjectListener('change', (data) => {
this._dispatchEvent('onChange', { data });
});
}
async doSomething(params: channels.MyDoSomethingParams): Promise<channels.MyDoSomethingResult> {
return { result: await this._object.doSomething(params.input) };
}
}