如何在Vapor Swift中通过SSE流式返回OpenAI聊天结果?
基于Vapor Swift实现OpenAI聊天流的SSE响应
你的现有代码用Promise仅返回了单次分片结果,无法实现SSE流式输出。要持续向客户端发送OpenAI的聊天流数据,需要利用Vapor的流式响应体,并遵循SSE格式规范输出内容。
修改后的实现代码
func postChatStreamHandler(_ req: Request) throws -> Response { let openAI = OpenAI(configuration: configuration) let query = ChatQuery(model: .gpt4, messages: messages) // 配置SSE响应头 var response = Response() response.headers.add(name: .contentType, value: "text/event-stream") response.headers.add(name: .cacheControl, value: "no-cache") response.headers.add(name: .connection, value: "keep-alive") // 创建流式响应体 response.body = .stream { writer in openAI.chatsStream(query: query) { partialResult in switch partialResult { case .success(let result): guard let _ = result.choices.first?.delta else { return } do { // 编码分片结果为JSON let data = try JSONEncoder().encode(result) guard let eventContent = String(data: data, encoding: .utf8) else { return } // 按照SSE格式封装事件:data: 内容\n\n let sseEvent = "data: \(eventContent)\n\n" let buffer = req.application.allocator.buffer(string: sseEvent) // 写入流 writer.write(buffer, promise: nil) } catch { writer.write(.error(error), promise: nil) } case .failure(let error): writer.write(.error(error), promise: nil) } } completion: { error in // 处理完成或错误,关闭流 if let error = error { writer.write(.error(error), promise: nil) } writer.close() } } return response }
关键说明
- 响应头配置:
text/event-stream标识这是SSE流,no-cache防止客户端缓存数据,keep-alive维持长连接 - 流式响应体:使用
.stream类型的响应体,通过writer对象逐次写入分片数据 - SSE格式规范:每个事件必须以
data: {内容}\n\n格式输出,客户端才能正确识别并处理流式数据 - 错误与关闭:在回调中处理异常情况,完成流传输后主动关闭writer,释放连接
内容的提问来源于stack exchange,提问作者Wendell
相关产品推荐
相关产品推荐

