微信小程序使用 SSE 流式输出,进行 Ai 对话

一.实现逻辑

1.使用 wx.request 开启流式输出(当然后端 也要开启 transfer-encoding: chunked)有些后端会默认开启 

this.requestTask = wx.request({
      url: 'xxxxxx',
      enableChunked: true, //开启 transfer-encoding chunked。
      method: 'POST',
      header: {
        'content-type': 'application/json',
        Authorization: `Bearer ${this.data.token}`
      },
      data: {
        question: message
      }
    })

2.使用 onChunkReceived 来监听返回的数据

    this.requestTask.onChunkReceived((res) => {
      console.log(res.data, 888)
      const parsed = this.decodeUint8Array(res.data)
      const temp = this.extractContentFromStream(parsed)
      console.log(temp)//转换之后的内容
    })

3.处理sse返回的数据(默认返回的是 ArrayBuffer(87) {} )

import encoding from '../../utils/encoding.js'
  
decodeUint8Array(uint8Array) {
    const data16 = this.buf2hex(uint8Array)
    const requestData = this.hexToStr(data16)
    return requestData
  },
  buf2hex(arrayBuffer) {
    return Array.prototype.map.call(new Uint8Array(arrayBuffer), (x) => ('00' + x.toString(16)).slice(-2)).join('')
  },

  hexToStr(hex) {
    let trimedStr = hex.trim()
    let rawStr = trimedStr.substr(0, 2).toLowerCase() === '0x' ? trimedStr.substr(2) : trimedStr
    let len = rawStr.length
    if (len % 2 !== 0) {
      return ''
    }
    let curCharCode 
    let resultStr = [] 
    for (let i = 0; i < len; i = i + 2) {
      curCharCode = parseInt(rawStr.substr(i, 2), 16)
      resultStr.push(curCharCode)
    }
    let bytesView = new Uint8Array(resultStr) 
    let str = new encoding.TextDecoder().decode(bytesView)
    return str
  }

4.需要两个文件 encoding.js 和 encoding-indexes.js 文件

二、问题

1.微信开发者工具中的 真机调试没反应(测试机 微信版本8.0.60)

   使用微信开发者工具的 预览 或者 上传体验版本 测试

2.在微信开发者工具中 即使你开启了  enableChunked: true, 数据也不是 流式返回,而是只响应了一次,一次性返回的

     升级最新版本的 微信开发者工具(我是这个原因,微信开发者工具太旧)

3.这时会遇到一个新的问题:微信开发者工具是 流式返回 但是真机测试又是一次性返回。。。。当时我真是吐血 ,看了微信开放社区 和 百度 ai 都没解决方法,最后发现是 后端 Nginx 配置问题 

location /products/ai/ {
    proxy_pass http://localhost:5000;      
    proxy_http_version 1.1;               
    proxy_set_header Connection "";        
    proxy_buffering off;                     
    chunked_transfer_encoding on;             
    proxy_hide_header Content-Length;        
}
后端在 nginx 加入之后 真机也能 流式返回

4.为什么会这样呢

因为后端使用的是 宝塔 ,默认会将 chunked 流式响应缓存/合并,有时即使后端返回 chunked,前端收到的却是带 Content-Length 的完整包,即是 一次性的返回数据,也就是说被 nginx 缓冲了流式输出,最终一次性返回。 上诉配置 就是 禁用缓存
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值