ChatGPT对话用Websocket和使用EventSource区别

当涉及实现 GPT 打字时,开发人员通常会考虑使用两种主要的技术:Microsoft 的 fetch-event-source 库和 WebSocket。这两种技术都能够实现实时的双向通信,但它们在一些方面有着不同的特点和适用场景。下面我们来对这两种技术进行对比。

fetch-event-source

microsoft/fetch-event-source是一个由Microsoft开发的JavaScript库,用于在浏览器中实现Fetch Event Source功能。Fetch Event Source是一种基于事件的HTTP客户端技术,用于从服务器端获取数据的推送通知。

优点:

  1. 简单易用: fetch-event-source 是一个基于 EventSource API 的库,使用起来非常简单。只需要创建一个 EventSource 实例并指定服务器端点,即可实现服务器端推送消息的接收。
  2. 基于 HTTP: fetch-event-source 底层基于 HTTP 协议,可以利用现有的 HTTP 基础设施进行通信。这意味着不需要额外的服务器端配置,也能够轻松地穿越防火墙。
  3. 适用于简单场景: 对于简单的实时通信需求,如实时聊天、通知推送等,fetch-event-source 是一个非常合适的选择。

缺点:

  1. 单向通信: fetch-event-source 只支持从服务器端向客户端的单向通信,无法实现客户端向服务器端的双向通信。
  2. 限制: 由于基于 HTTP 长连接,fetch-event-source 在某些情况下可能会受到连接超时、重连机制等限制。

以下是一个简单的示例,演示如何使用microsoft/fetch-event-source库来实现GPT打字

javascript 复制代码
import EventSource from 'microsoft-fetch-event-source';

// 创建一个新的EventSource对象,指定要连接的服务器端点
const eventSource = new EventSource('/gpt-typing');

// 监听服务器端发送的消息事件
eventSource.onmessage = function(event) {
  // 在收到消息时,将消息内容显示在页面上
  console.log('Received message:', event.data);
};

// 监听连接打开事件
eventSource.onopen = function(event) {
  // 连接成功时,可以执行一些操作
  console.log('Connection opened.');
};

// 监听连接关闭事件
eventSource.onclose = function(event) {
  // 连接关闭时,可以执行一些操作
  console.log('Connection closed.');
};

// 监听错误事件
eventSource.onerror = function(event) {
  // 发生错误时,可以执行一些操作
  console.error('Error occurred:', event);
};

// 当不再需要连接时,可以关闭EventSource对象
// eventSource.close();

在这个示例中,我们创建了一个新的EventSource对象,并指定了要连接的服务器端点'/gpt-typing'。然后,我们监听了几种事件,包括消息事件(onmessage)、连接打开事件(onopen)、连接关闭事件(onclose)和错误事件(onerror)。当服务器端发送消息时,会触发onmessage事件,并将消息内容显示在控制台上。

这样,我们就可以利用microsoft/fetch-event-source库来实现在浏览器中接收GPT打字的推送通知。

typescript 复制代码
import { useWebSocket } from '@vueuse/core'

export interface IWebSocketConfig {
  wsUrl: string
  isHeartbeat?: boolean
  isAutoReconnect?: boolean
  immediate?: boolean
  autoReconnect?: {
    retries?: number
    delay?: number
  }
  heartbeat?: {
    message?: string
    interval?: number
    pongTimeout?: number
  }
  onFailedCall?: Function
  onConnectedCall?: Function
  onDisconnectedCall?: Function
  onErrorCall?: Function
  onMessageCall?: Function
}

export const useWebSocketHook = (options?: IWebSocketConfig): any => {
  const {
    autoReconnect = {},
    isHeartbeat = false,
    isAutoReconnect = false,
    immediate = false,
    heartbeat = {},
    onConnectedCall,
    onDisconnectedCall,
    onErrorCall,
    onMessageCall,
    onFailedCall,
    wsUrl,
  } = options ?? {}

  const { status, data, send, open, close, ws } = useWebSocket(wsUrl, {
    autoReconnect: isAutoReconnect
      ? {
          retries: 3, // 最大重试次数。
          delay: 1000, // 延迟
          onFailed() {
            console.log('*** Failed to connect WebSocket after 3 retries ***')
            onFailedCall && onFailedCall()
          },
          ...autoReconnect,
        }
      : false,
    immediate: immediate,
    heartbeat: isHeartbeat
      ? {
          message: 'ping',
          interval: 1000,
          pongTimeout: 50000,
          ...heartbeat,
        }
      : false,
    onConnected(ws: WebSocket) {
      onConnectedCall && onConnectedCall(ws)
    },
    onDisconnected(ws: WebSocket, event: CloseEvent) {
      onDisconnectedCall && onDisconnectedCall(ws, event)
    },
    onError(ws: WebSocket, event: Event) {
      onErrorCall && onErrorCall(ws, event)
    },
    onMessage(ws: WebSocket, event: MessageEvent) {
      onMessageCall && onMessageCall(ws, event)
    },
  })

  return {
    status,
    data,
    send,
    open,
    close,
    ws,
  }
}

import { useWebSocketHook } from '@/hooks/useWebSocket'

const { send, open, close, data, status } = useWebSocketHook({
  isAutoReconnect: true,
  wsUrl: import.meta.env.VITE_SOCKET_URL,
  onConnectedCall: (ws: WebSocket) => {
    console.log('连接成功!', ws, status)
    state.wsReadyState = ws.readyState
    if (state.isSendData) {
      handleSendData()
    }
  },
  onMessageCall: () => {
    handleReceivedData(data.value)
  },
  onDisconnectedCall: (ws: WebSocket) => {
    console.log('断开连接!', ws)
    state.wsReadyState = ws.readyState
  },
  onErrorCall: (ws: WebSocket) => {
    console.log('连接失败!', ws.readyState)
    state.wsReadyState = ws.readyState
  },
  onFailedCall: () => {
    state.wsReadyState = -1
    state.isLoading = false
    state.generateLoading = false
  },
})

WebSocket

优点:

  1. 双向通信: WebSocket 支持全双工通信,客户端和服务器端都可以随时发送消息,实现实时的双向通信。
  2. 低延迟: WebSocket 使用 TCP 协议,相比 HTTP 长连接具有更低的延迟和更高的效率,适合实时性要求较高的场景。
  3. 灵活性: WebSocket 提供了更灵活的消息传输方式,可以发送文本、二进制数据等多种类型的消息。

缺点:

  1. 复杂度: 相对于 fetch-event-source,WebSocket 的使用稍显复杂,需要处理连接管理、心跳检测等细节。
  2. 部署限制: WebSocket 通常需要额外的服务器端配置和支持,某些环境下可能存在部署限制。

对比总结

  • 适用场景: 对于简单的实时通信需求,如消息通知、事件推送等,fetch-event-source 是一个简单、轻量级的选择;而对于需要实现双向通信、低延迟等要求较高的场景,则应选择 WebSocket。
  • 复杂度: fetch-event-source 更简单易用,适合于快速实现简单的实时通信功能;WebSocket 虽然稍显复杂,但提供了更多灵活性和功能扩展的可能性。
  • 性能和效率: WebSocket 相比 fetch-event-source 在延迟和效率上更有优势,特别是在需要大量实时数据传输的场景下,WebSocket 更能满足需求。

综上所述,开发人员应根据具体的需求和场景选择合适的技术来实现 GPT 打字功能。如果是简单的实时通信需求,fetch-event-source 可能更适合;而对于更复杂、性能要求更高的场景,则应选择 WebSocket。

相关推荐
学习前端的小z4 小时前
【AIGC】如何通过ChatGPT轻松制作个性化GPTs应用
人工智能·chatgpt·aigc
DisonTangor4 小时前
苹果发布iOS 18.2首个公测版:Siri接入ChatGPT、iPhone 16拍照按钮有用了
ios·chatgpt·iphone
晨欣4 小时前
Elasticsearch和Lucene之间是什么关系?(ChatGPT回答)
elasticsearch·chatgpt·lucene
光芒再现dev4 小时前
已解决,部署GPTSoVITS报错‘AsyncRequest‘ object has no attribute ‘_json_response_data‘
运维·python·gpt·语言模型·自然语言处理
爱技术的小伙子10 小时前
【ChatGPT】如何通过逐步提示提高ChatGPT的细节描写
人工智能·chatgpt
johnny23311 小时前
《大模型应用开发极简入门》笔记
笔记·chatgpt
ToToBe1 天前
L1G3000 提示工程(Prompt Engineering)
chatgpt·prompt
龙的爹23331 天前
论文 | Legal Prompt Engineering for Multilingual Legal Judgement Prediction
人工智能·语言模型·自然语言处理·chatgpt·prompt
bytebeats1 天前
我用 Spring AI 集成 OpenAI ChatGPT API 创建了一个 Spring Boot 小程序
spring boot·chatgpt·openai
知来者逆1 天前
使用 GPT-4V 全面评估泛化情绪识别 (GER)
人工智能·gpt·语言模型·自然语言处理·gpt-4v