剖析
- 使用
Deno.listen
监听 Socket 端口,Deno Core 使用 Rust 实现了 socket 这一套的编程; - 使用
Server
类中实现AsyncIterableIterator
来实现ServerRequest
的消费;
class Server implements AsyncIterable<ServerRequest> {
[Symbol.asyncIterator](): AsyncIterableIterator<ServerRequest> {
const mux: MuxAsyncIterator<ServerRequest> = new MuxAsyncIterator();
mux.add(this.acceptConnAndIterateHttpRequests(mux));
return mux.iterate();
}
}
MuxAsyncIterator
The MuxAsyncIterator class multiplexes multiple async iterators into asingle stream.
首先得理清楚基础概念:
Generator
Iterator
Iterable
AsyncGenerator
AsyncIterable
AsyncIterator
AsyncIterableIterator
```typescript interface AsyncIterator{ // NOTE: ‘next’ is defined using a tuple to ensure we report the correct assignability errors in all places. next(…args: [] | [TNext]): Promise >; return?( value?: TReturn | PromiseLike ): Promise >; throw?(e?: any): Promise >; }
interface AsyncGenerator
interface AsyncIterable
interface AsyncIterableIterator
然后尝试根据源代码,手动化简实现一个简单的 _MuxServer _来实现多 TCP 链接上 HTTPRequest 的多路复用,将多个流合并到一个处理模式下。
```typescript
class MuxServer implements AsyncIterable<string> {
private tcpConnectionPool: TCPConnection = new TCPConnection();
private async *iterateHttpRequests(conn: TCPConnection): AsyncIterableIterator<string> {
while(true) {
const msg = await conn.readHttpRequest();
yield msg;
}
}
private async *acceptConnAndIterateHttpRequests(mux: MuxAsyncIterator<string>): AsyncIterableIterator<string> {
const connectionMsg = await this.tcpConnectionPool.listen();
yield connectionMsg;
mux.add(this.acceptConnAndIterateHttpRequests(mux));
yield* this.iterateHttpRequests(this.tcpConnectionPool);
}
[Symbol.asyncIterator](): AsyncIterableIterator<string> {
const mux: MuxAsyncIterator<string> = new MuxAsyncIterator();
mux.add(this.acceptConnAndIterateHttpRequests(mux));
return mux.iterate();
}
}
这里是 Deno http 实现模块的精粹,但核心的网络编程还是交由 Rust 底层去实现的,这里就不作细节介绍了。
感受
人们总会不断尝试用新的事物去解决新的问题,AsyncIterable 的确让使用者以近乎同步的 code 写法实现异步事件和数据的消费,这的确是个比较好的编程写法,值得借鉴和学习。
在研究 MuxPlexer 多异步流合一的实现的时候,deno 的确给了一个比较好的实现范本,让我看到了 Rx.js 的影子。
Ref
这里是分享的 PPT: