UNPKG

@midwayjs/event-bus

Version:
335 lines (242 loc) 5.74 kB
# Event-Bus Event Bus 用来完成父子进程之间的消息传递,包括同步的调用,异步的发送,以及广播的能力,支持进程、线程、同一进程内调用三种模式。 ## Usage 基础使用,在不同的进程间引入。 如下,创建 Thread 模式的 EventBus。 ```ts /** * in main */ import { ThreadEventBus } from '@midwayjs/event-bus'; // 创建一个 bus const bus = new ThreadEventBus({ isWorker: false, }); // 添加一个 worker const worker = new Worker(); bus.addWorker(worker); // 等待连接和启动 await bus.start(); // 发布消息 bus.publish('hello world'); /** * in worker */ import { ThreadEventBus } from '@midwayjs/event-bus'; // 创建 bus 客户端 const bus = new ThreadEventBus({ isWorker: true, }); // 启动客户端,自动向 master 发送消息 await bus.start(); // 订阅消息 bus.subscribe(message => { console.log(message.body); // => 'hello world' }); ``` 可以创建 Cluster 模式的 EventBus,接口相同。 ```ts import { ChildProcessEventBus } from '@midwayjs/event-bus'; // in main const bus = new ChildProcessEventBus({ isWorker: false, }); await bus.start(); // in worker const bus = new ChildProcessEventBus({ isWorker: true, }); // 启动客户端,自动向 master 发送消息 await bus.start(); ``` 为了方便同进程研发,也提供了相同接口的 LocalEventBus。 ```ts import { LocalEventBus } from '@midwayjs/event-bus'; // in main const bus = new LocalEventBus({ isWorker: false, }); await bus.start(); // in worker const bus = new LocalEventBus({ isWorker: true, }); await bus.start(); ``` 注意,本地模式下,需要在不同文件中,且 worker 只能有一个。 ## API **start** bus 启动后,需要调用此方法,才能正常使用。 main 调用后会等待 worker 启动,worker 调用后会向 main 发送消息。 ```ts // in main & worker await bus.start(); ``` 如果 worker 启动错误,可以传递异常给 main。 ```ts // worker await bus.start(new Error('worker error')); // main bus.onError(error => { console.log(error.message); // => 'worker error' }); ``` **Publish & Subscribe** 异步的发送和监听消息,支持 main 和 worker 双向发送, API 一致。 ```ts bus.subscribe(message => { // message.body === {data: 'abc'} }); bus.publish({ data: 'abc' }); ``` 指定某个 topic 发送消息。 ```ts bus.subscribe(message => { // message.body === {data: 'abc'} }, { topic: 'test' }); bus.publish({ data: 'abc' }, { topic: 'test' }); ``` publish 错误。 ```ts const err = new Error('test'); bus.publish(err); ``` **publishAsync** 同步的发送消息,会等待订阅方返回,包含超时参数,默认 5s。支持 main <-> worker 双向异步通信。 从 main 发送到 worker: ```ts // in worker bus.subscribe((message, responder) => { // message.body === {data: 'abc'} responder?.send({ data: 'hello world', }); // send error responder.error(new Error('test')); }); // in main const result = await bus.publishAsync({ data: 'abc' }, { timeout: 5000, }); // result => {data: 'hello world'} ``` 从 worker 发送到 main: ```ts // in main bus.subscribe((message, responder) => { // message.body === {data: 'abc'} responder?.send({ data: 'hello world', }); }); // in worker const result = await bus.publishAsync({ data: 'abc' }, { timeout: 5000, }); // result => {data: 'hello world'} ``` 使用 try/catch 捕获错误: ```ts try { await bus.publishAsync({ data: 'abc' }); } catch (err) { // err.message => 'test' } ``` **publishChunk** 发送消息,会等待订阅方返回多次,包含超时参数,默认 5s。 此 API 仅限于 main 向 worker 发送消息。 `publishChunk` 方法返回的是一个异步迭代器。 ```ts // subscribe bus.subscribe((message, responder) => { responder.send('hello'); responder.send(' world'); responder.end(); }); // invoke const iterator = bus.publishChunk({ data: 'abc' }, { timeout: 5000, }); let result = ''; for await (const data of iterator) { result += data; } ``` 使用 try/catch 捕获错误。 ```ts const iterator = bus.publishChunk({ data: 'abc' }); try { let result = ''; for await (const data of iterator) { result += data; } } catch (err) { // err.message => 'test' } ``` **broadcast** 广播消息(一对多)。 ```ts // worker bus.subscribe(message => { // message.body === {data: 'abc'} }); // main bus.broadcast({ data: 'abc' }); ``` 也支持 worker 向其他 main 或者 worker 广播。 ```ts // worker bus.broadcast('hello world'); ``` 默认情况下,worker 广播之后,**main** 和 **当前 worker** 都不会收到这条消息 可以通过设置属性,让当前 Worker 也同时接收这条消息。 ```ts // worker bus.broadcast('hello world', { includeSelfFromWorker: true, }); ``` 可以通过设置属性,让 main 也同时接收这条消息。 ```ts // worker bus.broadcast('hello world', { includeMainFromWorker: true, }); ``` ## Message 类型 包含以下属性 - `messageId` 用来确定消息的唯一 id - `workerId` 消息发送的 worker id - `type` 消息发送的类型,包括 inited(初始化),request(main 向 worker 发送),response(worker 向 main 发送),invoke(同步的 main 向 worker 发送),broadcast(广播)几种类型 - `error` 意外的报错信息 - `messageOptions` 在发送消息时额外的参数,比如超时时间等,具体看类型定义 ## 调试 使用环境变量 `NODE_DEBUG=midway:event-bus*` 开启调试输出。 ## 注意 所有的消息必须可序列化,不能传递复杂对象,类,方法等。 ## License MIT