实战代码github代码:chatgpt-google-extension
该代码以Chrome 插件的实用案例讲解了 fetch-sse 的用法,之前这个技术被用得很少,大家基本上都直接用 websocket 了
谷歌插件:chatgpt-google-extension
简述下 SSE 是一个什么技术?以及怎么进行调用
fetch()
和 EventSource
都是用于实现服务器推送事件(Server-Sent Events,SSE)的技术,但它们在实现上有一些不同。下面是它们的优缺点:
fetch()
的优点:
-
更灵活的数据处理:使用
fetch()
方法可以更灵活地处理 SSE 数据流,因为我们可以使用 JavaScript 中的任何方法来处理和解析从 SSE 服务器端点接收的数据流。例如,我们可以使用TextDecoder
对象来解码数据流并将其转换为字符串,然后使用split()
方法将其拆分为多个行。 -
更高的兼容性:
fetch()
方法是一个标准的 Web API,支持所有主流的现代浏览器。因此,使用fetch()
方法可以获得更高的兼容性。 -
更好的控制权:使用
fetch()
方法可以更好地控制 SSE 数据流的读取和处理。我们可以手动控制 SSE 数据流的读取进度,而不是依赖于EventSource
对象的自动控制。
fetch()
的缺点:
-
需要手动解析数据:使用
fetch()
方法需要手动解析从 SSE 服务器端点接收的数据流,这需要一些额外的代码和技术。 -
无法自动重连:使用
fetch()
方法无法自动重连 SSE 服务器端点。如果与 SSE 服务器端点的连接断开,我们需要手动重新连接。 -
无法处理错误:使用
fetch()
方法无法处理 SSE 数据流的错误。如果发生错误,我们需要手动处理并调试代码。
EventSource
的优点:
-
自动重连:
EventSource
对象提供了自动重连的功能。如果与 SSE 服务器端点的连接断开,EventSource
对象会自动尝试重新连接,并恢复之前的数据流。 -
自动解析数据:
EventSource
对象自动解析从 SSE 服务器端点接收的数据流,并将其转换为 JavaScript 对象,方便我们进行处理和操作。 -
错误处理:
EventSource
对象提供了错误处理的功能。如果发生错误,EventSource
对象会触发错误事件,并提供错误信息,方便我们进行调试和处理。
EventSource
的缺点:
-
低兼容性:
EventSource
对象是一个 HTML5 新增的 Web API,可能不被所有的浏览器所支持。一些旧版的浏览器可能不支持EventSource
对象。 -
可能会出现内存泄漏:使用
EventSource
对象可能会出现内存泄漏的问题,特别是在长时间运行的情况下。因此,我们需要注意释放EventSource
对象。
综上所述,fetch()
方法和 EventSource
对象都有各自的优缺点。如果你需要更灵活的数据处理
给出两者的实现案例
以下是使用 fetch()
方法和 EventSource
对象实现 SSE 的代码示例:
使用 fetch()
方法:
const endpoint = 'http://example.com/sse';fetch(endpoint, { headers: { 'Accept': 'text/event-stream' },}).then(response => { const reader = response.body.getReader(); let buffer = ''; reader.read().then(function process({ done, value }) { if (done) { console.log('Stream closed'); return; } buffer += new TextDecoder('utf-8').decode(value); const lines = buffer.split('\n'); buffer = lines.pop(); lines.forEach(line => { console.log(line); }); // Continue reading return reader.read().then(process); });}).catch(error => { console.error(error);});
使用 EventSource
对象:
const endpoint = 'http://example.com/sse';const eventSource = new EventSource(endpoint);eventSource.addEventListener('open', event => { console.log('Connected to SSE server');});eventSource.addEventListener('message', event => { console.log(event.data);});eventSource.addEventListener('error', error => { console.error(error);});setTimeout(() => { eventSource.close(); console.log('Connection closed');}, 60000);
这两个代码示例分别使用了 fetch()
方法和 EventSource
对象来实现 SSE 技术。使用 fetch()
方法需要手动解析从 SSE 服务器端点接收的数据流,而使用 EventSource
对象则自动解析数据。使用 fetch()
方法需要手动控制 SSE 数据流的读取进度,而使用 EventSource
对象则自动控制。两种方式都可以实现 SSE,具体使用哪种方式取决于你的具体需求和场景。
如何弥补 fetch 的三个缺点?
好的,以下是整合在一起的代码示例:
const endpoint = 'http://example.com/sse';function connectSSE() { fetch(endpoint, { headers: { 'Accept': 'text/event-stream' }, }).then(response => { if (response.status !== 200) { // 报错 throw new Error(`Server responded with ${response.status}`); } const reader = response.body.getReader(); let buffer = ''; reader.read().then(function process({ done, value }) { if (done) { console.log('Stream closed'); // 自动重连 setTimeout(connectSSE, 1000); return; } buffer += new TextDecoder('utf-8').decode(value); const lines = buffer.split('\n'); buffer = lines.pop(); lines.forEach(line => { // 解析 SSE 数据 const data = parseSSEData(line); console.log(data); }); // Continue reading return reader.read().then(process); }).catch(error => { console.error(error); // 自动重连 setTimeout(connectSSE, 1000); }); }).catch(error => { console.error(error); // 自动重连 setTimeout(connectSSE, 1000); });}connectSSE();function parseSSEData(line) { const data = {}; const fields = line.split(':'); for (let i = 0; i < fields.length; i++) { const field = fields[i].trim(); if (i === 0) { // Event Type data.type = field; } else if (field.indexOf('data') === 0) { // Event Data data.data = field.substr(5); } else if (field.indexOf('id') === 0) { // Event ID data.id = field.substr(3); } else if (field.indexOf('retry') === 0) { // Retry Timeout data.retry = field.substr(6); } } return data;}
来源地址:https://blog.csdn.net/wangsenling/article/details/130490769