赞
踩
在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>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。