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

相关推荐
浮华似水21 分钟前
简洁之道 - React Hook Form
前端
正小安2 小时前
如何在微信小程序中实现分包加载和预下载
前端·微信小程序·小程序
小飞猪Jay4 小时前
C++面试速通宝典——13
jvm·c++·面试
_.Switch4 小时前
Python Web 应用中的 API 网关集成与优化
开发语言·前端·后端·python·架构·log4j
一路向前的月光4 小时前
Vue2中的监听和计算属性的区别
前端·javascript·vue.js
长路 ㅤ   4 小时前
vite学习教程06、vite.config.js配置
前端·vite配置·端口设置·本地开发
长路 ㅤ   4 小时前
vue-live2d看板娘集成方案设计使用教程
前端·javascript·vue.js·live2d
Fan_web4 小时前
jQuery——事件委托
开发语言·前端·javascript·css·jquery
安冬的码畜日常4 小时前
【CSS in Depth 2 精译_044】第七章 响应式设计概述
前端·css·css3·html5·响应式设计·响应式
莹雨潇潇5 小时前
Docker 快速入门(Ubuntu版)
java·前端·docker·容器