uniapp 微信小程序,最简单的流式输出:Transfer-Encoding: chunked

在GPT项目中,流式输出是实现流畅对话体验的关键技术之一。今天,我们将探讨如何在uniapp开发的微信小程序中优雅地实现这一功能。虽然WebSocket是一种常见的解决方案,但在某些场景下,我们可能寻求更轻量级且易于集成的替代方案。本文将介绍一种基于Transfer-Encoding: chunked的HTTP请求方式,它不仅避免了WebSocket的复杂性,同时也绕过了微信小程序对XHR和EventSource的限制。

在微信小程序环境下,由于平台限制,XHR和EventSource并不总是可用,而WebSocket的部署和维护成本相对较高。因此,我们探索了一种更为直接的方法——利用HTTP协议中的Transfer-Encoding: chunked特性。

实现细节:Transfer-Encoding: chunked
Transfer-Encoding: chunked允许服务器以分块的方式发送数据,而无需事先知道整个响应的大小。这种方式特别适合于流式输出场景,因为它可以实时地将数据推送给客户端,而无需等待整个响应构建完成。对于uniapp小程序而言,这意味着可以即时更新UI,提供更流畅的用户体验。

后台不需要改动,继续采用流式输出的形式即可,以通义千问的demo为例,代码如下

@RequestMapping(value = "/completions", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<Result<CompletionsOutMsg>> completions(@RequestBody CompletionsInMsg inMsg) {
    ....
}

客户端处理:uniapp小程序
在uniapp小程序端,需要监听网络请求的onProgressUpdate事件或使用onChunkReceived回调来处理分块数据。下面是一个处理分块数据的示例代码:

<template>
  <view class="page">
    <view class="box">
      <textarea class="uni-textarea" v-model="inputValue" placeholder="请输入内容"/>
    </view>
    <button class="mini-btn btn" type="primary" size="mini" @click="commit">提交</button>
    <view>
      {{ resultText }}
    </view>
  </view>
</template>

<script>
export default {
  data() {
    return {
      inputValue: '',
      resultText: '',
    };
  },
  methods: {
    commit() {
      var that = this;
      const requestTask = uni.request({
        url: 'YOUR_API_URL',
        method: 'POST',
        responseType: 'text',
        enableChunked: true,  //流式输出需要设置enableChunked为true
        data: {
          prompt: this.inputValue,
        },
        success: function (res) {
          console.log(JSON.stringify(res))
        },
        fail: function (err) {
        }
      });

      // 监听流式输出
      requestTask.onChunkReceived(function(res) {
        const uint8Array = new Uint8Array(res.data);
        let text = String.fromCharCode.apply(null, uint8Array);
        text = decodeURIComponent(escape(text));
        console.log(text);
        if (text) {
          let cleanedContent = text.replaceAll("data:", ',');
          let splitContent = "[" + cleanedContent.replace(/^,/, '') + "]";
          const dataArray = JSON.parse(splitContent);
          for (let i = 0; i < dataArray.length; i++) {
            that.resultText += dataArray[i].data.text;
          }
        }

      })


    },

  },


}
</script>

<style lang="scss">
.page {
  display: flex;
  justify-content: center;
  align-content: center;
  flex-direction: column;
}

.box {
  padding: 20rpx;
}

.btn {
  text-align: center;
  margin-top: 20rpx;
}

.uni-textarea {
  border: solid 1px #a59d9d;
  padding: 20rpx;
  width: 100%;
}

</style>

### 如何在 UniApp 小程序中使用通义千问 #### 集成背景 UniApp 是一个多端框架,支持开发者编写一次代码并部署到多个平台,其中包括微信小程序。而通义千问是一个强大的自然语言处理模型,能够提供高质量的文本生成能力。为了在 UniApp 开发的小程序中集成通义千问的功能,可以通过 HTTP 请求调用其 API 接口来完成交互。 #### 实现步骤概述 以下是实现 UniApp 和通义千问集成的核心要点: 1. **API 调用准备** 使用通义千问的服务通常需要先注册账号获取对应的 API 密钥,并按照官方文档配置好访问权限[^1]。这些密钥将在后续发起请求时作为认证参数传递给服务器。 2. **网络请求封装** 在 UniApp 中可以利用 `uni.request` 方法发送数据请求至阿里云提供的通义千问接口地址。需要注意的是,在实际应用过程中要妥善管理 token 或者其他形式的身份验证机制以保障安全性[^2]。 3. **流式加载优化** 对于实时性较高的应用场景比如聊天机器人界面设计,则可考虑采用分片传输编码(Transfer-Encoding: chunked)的方式来进行消息推送展示效果上的改进[^3]。这种方式相比传统一次性返回全部结果更加高效灵活,尤其适合移动端设备性能受限的情况。 4. **错误处理与用户体验提升** 此外还需注意异常情况下的友好提示以及重试逻辑设置等问题,从而提高整体系统的稳定性和易用程度。 #### 示例代码片段 下面给出一段简单的 JavaScript 代码用于演示如何向通义千问提交一个问题并通过回调函数接收答案: ```javascript // 发起对通义千问的问题查询 function askQuestion(questionText, callback){ const url = 'https://your-api-endpoint.com'; // 替换为真实的api endpoint let headerConfig={ "Content-Type":"application/json", Authorization:"Bearer YOUR_ACCESS_TOKEN" // 插入自己的access token }; uni.request({ method:'POST', url:url, data:{ prompt:questionText }, header:headerConfig, success(res){ if(res.statusCode===200 && res.data.choices){ callback(null,res.data.choices[0].text); }else{ console.error('Error:',res.errMsg||'Unknown error'); callback(new Error('Failed to get response from server')); } }, fail(err){ console.error('Network request failed',err); callback(new Error('Network issue occurred while contacting the service.')); } }); } askQuestion("你好!", function(error,response){ if(!error){ alert(`Answer is : ${response}`); }else{ alert(`Something went wrong:${error.message}`); } }); ```
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值