I need a way to send data to my client ios app from vapor backend on stream. I'm using openAI chat complation.
I used these code on my vapor backend, but these just retrieve reponse on a single payload.
func chatSteram(req: Request) async throws -> Response {
let chats = try req.content.decode([ChatQuery.ChatCompletionMessageParam].self)
let userName = req.headers.first(name: "userName")
guard (req.headers.first(name: "deviceUniqueId") != nil) else { throw Abort(.custom(code: 511, reasonPhrase: "user id required"))}
let query = ChatQuery(messages: chats, model: .gpt4_0125_preview, n: 1, temperature: 1, user: userName)
let body = Response.Body(stream: { writer in
let encoder = JSONEncoder()
Task {
do {
for try await res in req.openAI.chatsStream(query: query) {
if let data = try? encoder.encode(res), let string = String(data: data, encoding: .utf8) {
print("string response is \(string)")
_ = writer.write(.buffer(.init(string: string)))
}
}
} catch {
req.logger.error("Stream Error: \(error)")
}
_ = writer.write(.end)
}
})
let res = Response(status: .ok, body: body)
return res
}
but when I change do block to these
do {
for try await res in req.openAI.chatsStream(query: query) {
if let next = res.choices.first?.delta.content {
print("string response is \(string)")
_ = writer.write(.buffer(.init(string: string)))
}
}
}
these works as I exppected. but in my client side I need whole object, not just message.