ChatGPT API SSE(服务器推送技术)和 Fetch 请求 Accept: text/event-stream 标头案例

文章介绍了Server-SentEvents(SSE)技术,通过fetch()和EventSource实现SSE的优缺点,并提供了代码示例。fetch()方法更灵活但需手动处理数据和重连,而EventSource自动重连和解析数据,但兼容性较低。文章还展示了如何使用fetch()实现SSE的完整代码,包括自动重连和数据解析功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

实战代码github代码:chatgpt-google-extension
该代码以Chrome 插件的实用案例讲解了 fetch-sse 的用法,之前这个技术被用得很少,大家基本上都直接用 websocket 了
谷歌插件:chatgpt-google-extension

简述下 SSE 是一个什么技术?以及怎么进行调用

fetch()EventSource 都是用于实现服务器推送事件(Server-Sent Events,SSE)的技术,但它们在实现上有一些不同。下面是它们的优缺点:

fetch() 的优点:

  1. 更灵活的数据处理:使用 fetch() 方法可以更灵活地处理 SSE 数据流,因为我们可以使用 JavaScript 中的任何方法来处理和解析从 SSE 服务器端点接收的数据流。例如,我们可以使用 TextDecoder 对象来解码数据流并将其转换为字符串,然后使用 split() 方法将其拆分为多个行。

  2. 更高的兼容性:fetch() 方法是一个标准的 Web API,支持所有主流的现代浏览器。因此,使用 fetch() 方法可以获得更高的兼容性。

  3. 更好的控制权:使用 fetch() 方法可以更好地控制 SSE 数据流的读取和处理。我们可以手动控制 SSE 数据流的读取进度,而不是依赖于 EventSource 对象的自动控制。

fetch() 的缺点:

  1. 需要手动解析数据:使用 fetch() 方法需要手动解析从 SSE 服务器端点接收的数据流,这需要一些额外的代码和技术。

  2. 无法自动重连:使用 fetch() 方法无法自动重连 SSE 服务器端点。如果与 SSE 服务器端点的连接断开,我们需要手动重新连接。

  3. 无法处理错误:使用 fetch() 方法无法处理 SSE 数据流的错误。如果发生错误,我们需要手动处理并调试代码。

EventSource 的优点:

  1. 自动重连:EventSource 对象提供了自动重连的功能。如果与 SSE 服务器端点的连接断开,EventSource 对象会自动尝试重新连接,并恢复之前的数据流。

  2. 自动解析数据:EventSource 对象自动解析从 SSE 服务器端点接收的数据流,并将其转换为 JavaScript 对象,方便我们进行处理和操作。

  3. 错误处理:EventSource 对象提供了错误处理的功能。如果发生错误,EventSource 对象会触发错误事件,并提供错误信息,方便我们进行调试和处理。

EventSource 的缺点:

  1. 低兼容性:EventSource 对象是一个 HTML5 新增的 Web API,可能不被所有的浏览器所支持。一些旧版的浏览器可能不支持 EventSource 对象。

  2. 可能会出现内存泄漏:使用 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;
}
<think>嗯,用户遇到了Debian Jessie仓库无法更新的问题,提示“apt-secure repository does not have a Release file”。我需要先分析可能的原因。首先,Debian Jessie已经进入LTS阶段,可能官方仓库已经迁移到存档服务器了。原来的security仓库可能不再维护,导致Release文件缺失。 接下来,我应该检查用户是否还在使用旧的源列表。正确的做法是建议用户将源切换到archive.debian.org或者deb.debian.org的存档地址。此外,用户可能需要更新GPG密钥,因为旧的密钥可能已过期或被替换。 另外,用户可能没有正确配置源地址的组件,比如main、contrib、non-free部分是否齐全。需要提醒用户检查这些配置。还有,HTTPS支持可能需要安装apt-transport-https包,虽然Jessie默认应该支持,但确认一下也好。 然后,处理步骤应该包括修改sources.list文件,替换旧的URL,添加正确的deb行,可能还要导入新的密钥。最后执行apt-get update看看是否解决问题。如果还有其他问题,可能需要更详细的日志或者检查网络连接。 用户可能不太清楚如何编辑源列表,所以需要给出具体的命令示例,比如使用sed替换源地址,或者手动编辑文件。同时,提醒备份sources.list是个好习惯,防止出错。 最后,生成的相关问题应该覆盖常见后续疑问,比如如何完全升级系统、处理GPG错误、切换其他镜像源等。这样用户如果有其他问题,可以自行参考。</think>### Debian Jessie仓库Release文件缺失解决方案 Debian 8 "Jessie"已于2018年进入LTS(长期支持)阶段,其官方仓库已迁移至存档服务器。当出现"repository does not have a Release file"错误时,可按以下步骤修复: 1. **修改源列表** ```bash sudo sed -i 's/httpredir.debian.org/archive.debian.org/g' /etc/apt/sources.list sudo sed -i 's/security.debian.org/archive.debian.org\/debian-security/g' /etc/apt/sources.list ``` 2. **推荐的安全源配置** ```bash deb http://archive.debian.org/debian/ jessie main contrib non-free deb http://archive.debian.org/debian-security/ jessie/updates main ``` 3. **添加LTS支持源** ```bash deb http://deb.debian.org/debian jessie-backports main ``` 4. **更新软件包列表** ```bash sudo apt-get update -o Acquire::Check-Valid-Until=false ``` **注意**:需强制忽略过期时间戳检查[^1]。如果出现GPG错误,需导入新密钥: ```bash sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 8B48AD6246925553 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

森叶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值