面试官:你知道chatgpt是怎么做到实时对话的么

面试官:看你简历写着精通ChatGPT实现敏捷、高质量开发?那你知道它是如何做到实时对话的么?

我:web-socket?

面试官:回去等通知吧~

之后翻阅才知道ChatGPT用的是EventSource,相比其他的通信如Web-socket而言它更轻量级和简单 ,且对资源消耗 更少,最重要一个原因是GPT主要关注从服务器向客户端推送消息的场景,而不需要客户端主动向服务器发送消息。EventSource正是为此类单向通信 设计的,它允许服务器发送事件到客户端,而客户端只能接收事件,不能发送。对于ChatGPT这样的应用来说,这种单向通信模式可能就足够了。

废话不多说,我们来看看EventSource的基本用法

基本用法

EventSource是HTML5中新增的一个API,它允许服务器通过HTTP连接向客户端推送消息。与传统的HTTP请求-响应模式不同,EventSource使用了一个持久的连接,使得服务器可以在任何时候向客户端发送数据。这种单向通信模式非常适合用于实时更新、实时通知等场景。

  1. 关键特性
    • 服务器向客户端单向推送数据。
    • 基于HTTP长连接,连接一旦建立,服务器可以持续发送数据直到连接关闭。
    • 客户端通过监听特定事件(如message)来接收服务器发送的数据。
  2. 常用方法
    • new EventSource(url): 创建一个新的EventSource对象,并连接到指定的URL。
    • EventSource.onmessage: 当服务器发送数据时触发的事件处理函数。
    • EventSource.onerror: 当连接发生错误时触发的事件处理函数。
    • EventSource.onopen: 当连接建立时触发的事件处理函数(注意:并非所有浏览器都支持此事件)。
    • EventSource.close(): 关闭连接。

实际应用场景

假设我们正在开发一个实时股票行情应用,需要实时显示股票价格的变动。使用EventSource,我们可以轻松地实现这一功能。

服务器端可以设置为定期从股票数据API获取最新价格,并通过EventSource发送给客户端。客户端则监听message事件,一旦接收到新数据,就更新页面上的股票价格。

这种方式下,客户端无需不断轮询服务器以获取最新数据,从而减少了不必要的网络请求和服务器负载。同时,由于EventSource是基于HTTP的,因此它可以轻松地穿透防火墙和代理服务器,提高了应用的可用性和稳定性。

接下来我们实战看看

实战例子

拿Vue为例子

xml 复制代码
<template>
  <div v-html="html">
    
  </div>
</template>

<script>
export default {

  data() {
    return {
      html: '' 
    }
  },

  mounted() {
    this.handleEventSoure()
  },

  methods: {

    handleEventSoure() {
      const eventSource = new EventSource('/api/messages') // 连接地址

      eventSource.onopen = () => { // 开始连接
      }

      eventSource.onmessage = (event) => { // 接收消息
         this.html += `${event.data} </br>`
      }

      eventSource.onerror = () => { // 连接失败
      }
    }
  }
}
</script>

通过new EventSource进行对服务器的连接,并且配置相关连接处理函数。

后端则用node+express为例子

javascript 复制代码
app.get('/messages', (req, res) => {  

  // 设置响应头,指明这是一个EventSource响应  
  res.setHeader('Content-Type', 'text/event-stream')  
  // 禁用缓存
  res.setHeader('Cache-Control', 'no-cache')

  // 保持长连接
  res.setHeader('Connection', 'keep-alive')  
  
  // 发送一个初始消息  
  res.write('data: 连接成功\n\n')  
  
  // 连接关闭
  req.on('close', () => {})  
  
  // 创建一个定时器来定期发送事件  
  const interval = setInterval(() => {  
    if (res.writable) {  
      const message = `时间: ${new Date().toISOString()}`  
      res.write(`data: ${message}\n\n`)  
    } else {  
      // 如果连接不再可写(可能已经关闭),则清除定时器  
      clearInterval(interval)  
    }  
  }, 1000) // 每1秒发送一次事件  
  
  // 当请求结束时(例如,客户端关闭连接),清除定时器  
  req.on('end', () => {  
    clearInterval(interval)  
  })  
})  

接下来我们看看效果吧:

EventSource是一种简单且有效的实时通信协议,它利用HTTP长连接实现了服务器向客户端的单向数据推送。通过合理使用EventSource的API和方法,我们可以轻松地构建出实时更新、实时通知等功能的Web应用。在实际应用中,我们需要根据具体需求选择合适的通信协议和方式,以实现相关业务。

相关推荐
景天科技苑1 分钟前
【vue3+vite】新一代vue脚手架工具vite,助力前端开发更快捷更高效
前端·javascript·vue.js·vite·vue项目·脚手架工具
小行星12512 分钟前
前端预览pdf文件流
前端·javascript·vue.js
join813 分钟前
解决vue-pdf的签章不显示问题
javascript·vue.js·pdf
小行星12519 分钟前
前端把dom页面转为pdf文件下载和弹窗预览
前端·javascript·vue.js·pdf
Lysun00128 分钟前
[less] Operation on an invalid type
前端·vue·less·sass·scss
J总裁的小芒果44 分钟前
Vue3 el-table 默认选中 传入的数组
前端·javascript·elementui·typescript
Lei_zhen961 小时前
记录一次electron-builder报错ENOENT: no such file or directory, rename xxxx的问题
前端·javascript·electron
咖喱鱼蛋1 小时前
Electron一些概念理解
前端·javascript·electron
yqcoder1 小时前
Vue3 + Vite + Electron + TS 项目构建
前端·javascript·vue.js
长风清留扬1 小时前
一篇文章了解何为 “大数据治理“ 理论与实践
大数据·数据库·面试·数据治理