面试官:你知道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应用。在实际应用中,我们需要根据具体需求选择合适的通信协议和方式,以实现相关业务。

相关推荐
majingming1235 小时前
FUNCTION
java·前端·javascript
A_nanda6 小时前
Vue项目升级
前端·vue3·vue2
SuperEugene6 小时前
Axios 接口请求规范实战:请求参数 / 响应处理 / 异常兜底,避坑中后台 API 调用混乱|API 与异步请求规范篇
开发语言·前端·javascript·vue.js·前端框架·axios
abigale037 小时前
【浏览器 API / 网络请求 / 文件处理】前端文件上传全流程:从基础上传到断点续传
前端·typescript·文件上传·vue cli
Setsuna_F_Seiei7 小时前
AI 对话应用之页面滚动交互的实现
前端·javascript·ai编程
新缸中之脑7 小时前
追踪来自Agent的Web 流量
前端
wefly20178 小时前
从使用到原理,深度解析m3u8live.cn—— 基于 HLS.js 的 M3U8 在线播放器实现
java·开发语言·前端·javascript·ecmascript·php·m3u8
小江的记录本8 小时前
【事务】Spring Framework核心——事务管理:ACID特性、隔离级别、传播行为、@Transactional底层原理、失效场景
java·数据库·分布式·后端·sql·spring·面试
寂静or沉默8 小时前
2026最新Java岗位从P5-P7的成长面试进阶资源分享!
java·开发语言·面试
英俊潇洒美少年8 小时前
vue如何实现react useDeferredvalue和useTransition的效果
前端·vue.js·react.js