当涉及实现 GPT 打字时,开发人员通常会考虑使用两种主要的技术:Microsoft 的 fetch-event-source 库和 WebSocket。这两种技术都能够实现实时的双向通信,但它们在一些方面有着不同的特点和适用场景。下面我们来对这两种技术进行对比。
fetch-event-source
microsoft/fetch-event-source是一个由Microsoft开发的JavaScript库,用于在浏览器中实现Fetch Event Source功能。Fetch Event Source是一种基于事件的HTTP客户端技术,用于从服务器端获取数据的推送通知。
优点:
- 简单易用: fetch-event-source 是一个基于 EventSource API 的库,使用起来非常简单。只需要创建一个 EventSource 实例并指定服务器端点,即可实现服务器端推送消息的接收。
- 基于 HTTP: fetch-event-source 底层基于 HTTP 协议,可以利用现有的 HTTP 基础设施进行通信。这意味着不需要额外的服务器端配置,也能够轻松地穿越防火墙。
- 适用于简单场景: 对于简单的实时通信需求,如实时聊天、通知推送等,fetch-event-source 是一个非常合适的选择。
缺点:
- 单向通信: fetch-event-source 只支持从服务器端向客户端的单向通信,无法实现客户端向服务器端的双向通信。
- 限制: 由于基于 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
优点:
- 双向通信: WebSocket 支持全双工通信,客户端和服务器端都可以随时发送消息,实现实时的双向通信。
- 低延迟: WebSocket 使用 TCP 协议,相比 HTTP 长连接具有更低的延迟和更高的效率,适合实时性要求较高的场景。
- 灵活性: WebSocket 提供了更灵活的消息传输方式,可以发送文本、二进制数据等多种类型的消息。
缺点:
- 复杂度: 相对于 fetch-event-source,WebSocket 的使用稍显复杂,需要处理连接管理、心跳检测等细节。
- 部署限制: WebSocket 通常需要额外的服务器端配置和支持,某些环境下可能存在部署限制。
对比总结
- 适用场景: 对于简单的实时通信需求,如消息通知、事件推送等,fetch-event-source 是一个简单、轻量级的选择;而对于需要实现双向通信、低延迟等要求较高的场景,则应选择 WebSocket。
- 复杂度: fetch-event-source 更简单易用,适合于快速实现简单的实时通信功能;WebSocket 虽然稍显复杂,但提供了更多灵活性和功能扩展的可能性。
- 性能和效率: WebSocket 相比 fetch-event-source 在延迟和效率上更有优势,特别是在需要大量实时数据传输的场景下,WebSocket 更能满足需求。
综上所述,开发人员应根据具体的需求和场景选择合适的技术来实现 GPT 打字功能。如果是简单的实时通信需求,fetch-event-source 可能更适合;而对于更复杂、性能要求更高的场景,则应选择 WebSocket。