读一下@microsoft/fetch-event-source源码

做过两个大模型聊天的项目,也是从那时起知道了SSE(Server-Sent Events),进而又知道了@microsoft/fetch-event-source。

今天有空把自己知道的做一个总结,便于以后查阅,主要是浅读一下@microsoft/fetch-event-source这个库的源码。

基本的SSE概念可以参考https://www.ruanyifeng.com/blog/2017/05/server-sent_events.html和https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events。

既然有了浏览器原生支持的EventSource为什么还要@microsoft/fetch-event-source,可以参考@microsoft/fetch-event-source中提到的
在这里插入图片描述
大体意思是:原生EventSource只有get请求参数只能通过url传递,不能传递自定义的请求头,重试机制我们不能插手。而它解决了以上的问题。同时你还能拿到Response对象。

现在有很多前端项目,跟后端的鉴权机制是通过在请求头中添加Authorization,用原生的EventSource就不行。

接下来让我们看一下@microsoft/fetch-event-source源码吧

0. 克隆代码

git clone https://github.com/Azure/fetch-event-source.git

1. 目录结构

在这里插入图片描述
src目录中有以上4个文件,parse.spec.ts是用来做单元测试的,这里就不看了。index.ts只是简单的导出,也不看了。fetch.ts负责发送请求,parse.ts负责把请求返回的数据解析出消息。

2. fetch.ts

这个文件中最主要的就是fetchEventSource函数,也是这个库的最主要的内容。它的主要流程是调用fetch发送请求,用parse.ts中的函数解析响应返回的流得到一个个消息(事件)

FetchEventSourceInit是fetchEventSource函数的第二个参数的类型定义,它包括

字段 含义
headers 请求头,Record<string, string>
onopen 响应回来调用的回调
onmessage 接收到消息时的回调
onclose 响应结束时的回调
onerror 报错时的回调
openWhenHidden 页面隐藏时是否依旧开这连接
fetch 自定义的fetch,默认使用window.fetch

方法defaultOnOpen, 默认的onopen回调,判断响应的Content-Type是否text/event-stream,如果不是则抛出异常。

方法fetchEventSource

  1. 请求headers补上accept,值为text/event-stream
  2. 根据参数openWhenHidden,决定是否注册visibilitychange事件,用来实现页面隐藏后取消请求,页面重新显示后重新发送请求。这个机制可以借鉴
  3. 给参数signal注册abort事件,这样在外部调用AbortController的abort时,这里就能取消请求了,调用了dispose和resolve
  4. 调用create方法发送请求
    • 创建AbortController实例curRequestController,把它的signal传递给fetch,实现取消请求的功能
    • 使用fetch发送请求
    • 回调onopen
    • 读取响应流,直到结束,读流
    • 回调onclose
    • 调用dispose和resolve

3. parse.ts

这个文件提供了对返回的流进行解析的函数。

  • getBytes
    调用ReadableStream实例的getReader方法获得ReadableStreamDefaultReader实例,然后循环调用ReadableStreamDefaultReader的read方法直到流结束,read方法返回的是ReadableStreamReadResult,它的value属性就是流的内容,是Unit8Array类型的。
  • getLines
    解析getBytes读取的Unit8Array对象,从中得到行。
  • getMessage
    解析getLines中得到的行,得到消息,遇到空行认为是一个消息的结束。

这里的解析过程让我想起了表达式的解析,有借鉴意义,同时这里对于高阶函数的运用让人眼前一亮!

连接关闭的问题

在实践过程中,我遇到了请求关闭的问题。从前端不论是原生的EventSource的close或是fetchEventSource的signal都能实现关闭请求。但是对于原生的EventSource却无法单

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值