使用 Uint8Array
和 ReadableStream
模拟服务器发送事件 (SSE)
1. 背景
在 Web 开发中,服务器发送事件(SSE)是一种允许服务器主动向客户端发送数据的机制。为了模拟 SSE,我们可以使用 ReadableStream
和 Uint8Array
来处理和传输二进制数据。
2. Uint8Array
Uint8Array
是一种类型化数组,用于处理原始二进制数据。每个元素都是 8 位无符号整数(0 到 255),占用一个字节的内存。
-
创建
Uint8Array
:const uint8 = new Uint8Array([0, 255, 128, 64]); console.log(uint8); // 输出: Uint8Array(4) [0, 255, 128, 64]
-
常用方法:
const uint8 = new Uint8Array(4); uint8.set([10, 20, 30, 40]); console.log(uint8); // 输出: Uint8Array(4) [10, 20, 30, 40]
3. TextEncoder
TextEncoder
是用于将字符串编码为 Uint8Array
的对象,使用 UTF-8 编码方案。
- 使用示例:
const encoder = new TextEncoder(); const uint8Array = encoder.encode("Hello, world!"); console.log(uint8Array); // 输出: Uint8Array(13) [72, 101, 108, 108, 111, 44, 32, 119, 111, 114, 108, 100, 33]
4. ReadableStreamDefaultController
ReadableStreamDefaultController
用于控制 ReadableStream
的状态,包括推送数据块、关闭流和处理错误。
- 常用方法:
enqueue(chunk)
: 将数据块推送到流中。close()
: 关闭流。error(e)
: 将流置于错误状态。
5. 使用 ReadableStream
模拟 SSE
通过结合 Uint8Array
、TextEncoder
和 ReadableStreamDefaultController
,我们可以创建一个模拟 SSE 的类。
export class MockSSEResponse { private controller!: ReadableStreamDefaultController<Uint8Array>; private encoder = new TextEncoder(); private stream: ReadableStream<Uint8Array>; constructor( private dataArray: string[], private delay: number = 300, ) { this.stream = new ReadableStream({ start: (controller) => { this.controller = controller; this.pushData(); }, }); } private pushData() { if (this.dataArray.length === 0) { this.controller.close(); // 数据发送完毕,关闭流 return; } const chunk = this.dataArray.shift(); this.controller.enqueue(this.encoder.encode(chunk!)); // 编码并推送数据块 setTimeout(() => this.pushData(), this.delay); // 延迟后递归调用 } getResponse() { return new Response(this.stream); } }
- 构造函数: 初始化
dataArray
和delay
,并创建一个新的ReadableStream
实例。 pushData
方法: 从dataArray
中获取数据块,使用TextEncoder
编码为Uint8Array
,然后使用enqueue
方法推送到流中。重复此操作直到所有数据发送完毕,并关闭流。getResponse
方法: 返回包含流的Response
对象。
结论
使用 Uint8Array
和 ReadableStream
可以有效地模拟服务器发送事件(SSE),通过 TextEncoder
将字符串数据编码为二进制数据,并通过 ReadableStreamDefaultController
控制数据流的推送和关闭。这个方法在开发和测试需要模拟 SSE 场景时非常有用。