前端 AI 对话的四种实现方案及最佳实践

58 阅读2分钟

前言

AI 对话已成为前端应用的必备功能,如何优雅地处理实时对话数据成为一个关键问题。本文将从 SSE、WebSocket、轮询到小程序专属方案,详细对比四种实现方式的优劣,帮助你在不同场景下选择最适合的解决方案。

实现方案对比

方案优点缺点适用场景
SSE实现简单,实时性好只支持单向通信标准 Web 环境
微信小程序 enableChunked小程序原生支持仅限微信小程序微信小程序环境
轮询兼容性好,实现简单服务器压力大,实时性差受限环境(如企业微信)
webSocket全双工通信,实时性好实现复杂,需要维护连接对实时性要求高的场景

Server-Sent Events (SSE)

SSE 是一种服务器推送技术,允许服务器向客户端推送数据。它基于 HTTP 协议,单向通信(服务器到客户端)

async function* streamEvents<R = any>(readableStream: ReadableStream<Uint8Array>) {
    const reader = readableStream.getReader();
    const decoder = new TextDecoder('utf-8');
    let data = '';
    while (true) {
      const { done, value } = await reader.read();
      if (done) break;
      data += decoder.decode(value, { stream: true });
  
      while (true) {
        const newlineIndex = data.indexOf('\n');
        if (newlineIndex === -1) break;
        const line = data.slice(0, newlineIndex);
        data = data.slice(newlineIndex + 1);
        if (line.startsWith('data:')) {
          const text = line.slice('data:'.length).trim();
          try {
            const parsed = JSON.parse(text) as R
            yield parsed;
          } catch {
            console.warn('Invalid JSON:', text);
          }
        }
      }
    }
}
// 使用示例
const stream = await fetch('xxx',{body: JSON.stringify({stream: true})});
const events = streamEvents(stream.body);
for await (const event of events) {
  console.log(event);
}

微信小程序 enableChunked

微信小程序不支持 sse,但它提供了 enableChunked 来支持流式数据接收

const requestTask = wx.request({
    url: `xxx`,
    method: 'POST',
    responseType: 'arraybuffer',
    enableChunked: true,
    // ...
});
requestTask.onChunkReceived(({ data }) => {
    const uint8Array = new Uint8Array(data);
    let text = String.fromCharCode.apply(null, uint8Array);
    text = decodeURIComponent(escape(text));
    if (data.indexOf('\n') !== -1) {
        cosnole.log(text);
    } else {
        // end
    }
});

注意 sse 和 微信小程序 enableChunked 都需要特定 nginx 配置

proxy_set_header Transfer-Encoding ""; 
chunked_transfer_encoding on; 
proxy_buffering off;

企业微信环境下的轮询方案

由于企业微信环境的限制(不支持 SSE 和 enableChunked),可以采用轮询方案 实现思路: 发送消息时,服务端返回一个id,客户端根据id定期发送请求,查询是否有新数据,服务端使用 Redis 等存储中间数据

websocket

webSocket 提供了全双工通信能力,是实现实时对话的理想选择,但需要考虑更多的实现细节

总结

选择合适的 AI 对话实现方案需要考虑以下因素:

  1. 运行环境的限制
  2. 实时性要求
  3. 开发维护成本
  4. 服务器负载

不同场景下的最佳实践:

  • Web 环境:优先考虑 SSE
  • 微信小程序:使用 enableChunked
  • 受限环境:采用轮询方案
  • 高实时性需求:考虑 webSocket