当前位置:   article > 正文

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

uniapp enablechunked

在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为例,代码如下

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

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

  1. <template>
  2. <view class="page">
  3. <view class="box">
  4. <textarea class="uni-textarea" v-model="inputValue" placeholder="请输入内容"/>
  5. </view>
  6. <button class="mini-btn btn" type="primary" size="mini" @click="commit">提交</button>
  7. <view>
  8. {{ resultText }}
  9. </view>
  10. </view>
  11. </template>
  12. <script>
  13. export default {
  14. data() {
  15. return {
  16. inputValue: '',
  17. resultText: '',
  18. };
  19. },
  20. methods: {
  21. commit() {
  22. var that = this;
  23. const requestTask = uni.request({
  24. url: 'YOUR_API_URL',
  25. method: 'POST',
  26. responseType: 'text',
  27. enableChunked: true, //流式输出需要设置enableChunked为true
  28. data: {
  29. prompt: this.inputValue,
  30. },
  31. success: function (res) {
  32. console.log(JSON.stringify(res))
  33. },
  34. fail: function (err) {
  35. }
  36. });
  37. // 监听流式输出
  38. requestTask.onChunkReceived(function(res) {
  39. const uint8Array = new Uint8Array(res.data);
  40. let text = String.fromCharCode.apply(null, uint8Array);
  41. text = decodeURIComponent(escape(text));
  42. console.log(text);
  43. if (text) {
  44. let cleanedContent = text.replaceAll("data:", ',');
  45. let splitContent = "[" + cleanedContent.replace(/^,/, '') + "]";
  46. const dataArray = JSON.parse(splitContent);
  47. for (let i = 0; i < dataArray.length; i++) {
  48. that.resultText += dataArray[i].data.text;
  49. }
  50. }
  51. })
  52. },
  53. },
  54. }
  55. </script>
  56. <style lang="scss">
  57. .page {
  58. display: flex;
  59. justify-content: center;
  60. align-content: center;
  61. flex-direction: column;
  62. }
  63. .box {
  64. padding: 20rpx;
  65. }
  66. .btn {
  67. text-align: center;
  68. margin-top: 20rpx;
  69. }
  70. .uni-textarea {
  71. border: solid 1px #a59d9d;
  72. padding: 20rpx;
  73. width: 100%;
  74. }
  75. </style>

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/寸_铁/article/detail/844861
推荐阅读
相关标签
  

闽ICP备14008679号