当前位置:   article > 正文

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

fetch text/event-stream

实战代码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);
});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

使用 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);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

这两个代码示例分别使用了 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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/335446
推荐阅读
相关标签
  

闽ICP备14008679号