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。

相关推荐
B2_Proxy10 小时前
亚马逊采集的正确打开方式:从合规边界到反爬博弈,再到数据价值落地
服务器·网络·网络协议·tcp/ip·chatgpt
yuhulkjv33510 小时前
ChatGPT和Gemini复制到word格式
chatgpt·word
yuhulkjv33513 小时前
deepseek能导出图片
人工智能·chatgpt
jianwuhuang8214 小时前
豆包内容导出图片
人工智能·chatgpt
wujian831114 小时前
ChatGPT和Gemini导出pdf方法
人工智能·ai·chatgpt·pdf·deepseek
卖芒果的潇洒农民1 天前
20260201 GPT VPC中的CIDR Block 概念
笔记·gpt
aihuangwu2 天前
ChatGPT和Gemini图表怎么导出
人工智能·ai·chatgpt·deepseek·ds随心转
薛定谔的猫19822 天前
二十、使用PyTorch和Hugging Face Transformers训练中文GPT-2模型的技术实践
人工智能·pytorch·gpt
这是个栗子2 天前
AI辅助编程(一) - ChatGPT
前端·vue.js·人工智能·chatgpt
新缸中之脑3 天前
ChatGPT 容器
chatgpt