用vue2+chatGPT如何实现流式输出?

我是使用EventSource去实现的,可显示的话和访问普通接口一样是全部一次性显示出来,以下是我的代码

<div v-for="(item,index) in items" :key="index" :class="item.user==='bot'? 'chat-reply':'chat-question'">
            <div v-html="item.html? item.html : item.message || ''"></div>
</div>

let sse = new EventSource(`http://localhost:8080/api/openai/completions/stream?user=${this.user}&prompt=${this.message}`)
let this_ = this
this_.items.push({user: 'user', messageType: 'TEXT', message: this_.message})
this_.message = ''
sse.addEventListener('open', (function () {
  this_.generating = true
  this_.items.push({user: 'bot', messageType: 'TEXT', message: ''})
                        }))
sse.addEventListener('message', function (res) {
      let resJson = JSON.parse(res.data)
      if (resJson.code !== 0) {
          this_.generating = false
          alert("处理失败:" + resJson.msg)
          sse.close()
          return
      }
      resJson = resJson.data

      if (resJson.messageType === 'TEXT') {
          if (resJson.end === true) {

              sse.close()
              this_.generating = false
          } else {
            let index = this_.items.length - 1
            let obj = {
              user: 'bot',
              messageType: 'TEXT',
              message: this_.items[index].message + resJson.message,
              html: ''
            };
            this_.$set(this_.items, index, obj)
          }
          //图片
      } else {
          
      }

  }
)
        
  sse.addEventListener('error', function () {
      alert('服务器错误,请查看日志')
  })

请问要如何才可以实现和chatGPT一样效果的流式输出
tips:我自己用网页访问接口数据是一条一条输出的,可是在控制台看的话也是一瞬全部出来,虽然是分很多条

阅读 3.9k
avatarAI BotBETA

在您的问题中,您提到了使用Vue 2和ChatGPT来实现流式输出。您的代码使用了EventSource来获取数据,但是数据显示的方式是全部一次性显示出来,而不是流式输出。

要实现类似于ChatGPT的流式输出效果,您可以使用WebSocket或者Server-Sent Events(SSE)来实时接收数据并更新界面。

以下是一个使用WebSocket的示例代码,可以实现流式输出效果:

<template>
  <div>
    <div v-for="(item, index) in items" :key="index" :class="item.user === 'bot' ? 'chat-reply' : 'chat-question'">
      <div v-html="item.html ? item.html : item.message || ''"></div>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      items: [],
      socket: null,
    };
  },
  created() {
    this.socket = new WebSocket(`ws://localhost:8080/api/openai/completions/stream?user=${this.user}&prompt=${this.message}`);
    this.socket.onmessage = this.handleMessage;
  },
  methods: {
    handleMessage(event) {
      const data = JSON.parse(event.data);
      if (data.code !== 0) {
        alert("处理失败:" + data.msg);
        this.socket.close();
        return;
      }
      data = data.data;
      if (data.messageType === 'TEXT') {
        if (data.end === true) {
          this.socket.close();
        } else {
          const index = this.items.length - 1;
          const obj = {
            user: 'bot',
            messageType: 'TEXT',
            message: this.items[index].message + data.message,
            html: '',
          };
          this.$set(this.items, index, obj);
        }
      } else {
        // 处理图片或其他类型的消息
      }
    },
  },
};
</script>

在上面的代码中,我们使用了WebSocket来建立与服务器之间的实时连接。当服务器发送消息时,handleMessage方法会被调用,并接收到服务器发送的数据。然后根据数据的类型和内容,更新界面上的显示。当收到结束消息时,关闭WebSocket连接。这样,聊天记录就会以流式输出方式实时显示在界面上。

1 个回答
新手上路,请多包涵

可以使用event-source-polyfill这个插件,这个需要后端来配合,可以实现流式输出

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题