EventSource

CI

EventSource 是一个 Swift 包,它为 Server-Sent Events (SSE) 提供了一个简单的客户端实现。 它允许您通过简单高效的接口,轻松地通过持久的 HTTP 连接从服务器接收实时更新。

它还利用 Swift 的并发特性,提供了一种更具表现力和直观的方式来处理异步操作。

注意

请注意,此包最初是为与其他包一起使用而开发的,因此,它可能未涵盖所有规范细节。 在评估 EventSource 是否适合您的特定用例时,请注意此限制。

特性

安装

该包的模块名称为 EventSource。 选择以下说明之一进行安装,并将以下导入语句添加到您的源代码中。

import EventSource

Xcode 包依赖

从 Xcode 菜单: File > Swift Packages > Add Package Dependency

https://github.com/Recouse/EventSource

Swift Package Manager

在您的 Package.swift 文件中,首先将以下内容添加到 package 的 dependencies

.package(url: "https://github.com/Recouse/EventSource.git"),

然后,将 "EventSource" 作为目标依赖项包含进去

.target(name: "<target>", dependencies: [
    .product(name: "EventSource", package: "EventSource"),
]),

用法

使用 EventSource 非常简单。 只需从 EventSource 的实例中创建一个新的数据任务,其中包含您要连接的 SSE 端点的 URLRequest,然后等待事件即可

import EventSource

let eventSource = EventSource()
let dataTask = await eventSource.dataTask(for: urlRequest)

for await event in await dataTask.events() {
    switch event {
    case .open:
        print("Connection was opened.")
    case .error(let error):
        print("Received an error:", error.localizedDescription)
    case .event(let event):
        print("Received an event", event.data ?? "")
    case .closed:
        print("Connection was closed.")
    }
}

使用 dataTask.cancel() 显式关闭连接。 但是,在这种情况下,不会发出 .closed 事件。

仅数据模式

EventSource 可以以仅数据模式使用,使其适用于流行的 API,例如 OpenAI。 下面是使用 OpenAI 的 completions API 的示例

var urlRequest = URLRequest(url: URL(string: "https://api.openai.com/v1/chat/completions")!)
urlRequest.allHTTPHeaderFields = [
    "Content-Type": "application/json",
    "Authorization": "Bearer \(accessToken)"
]
urlRequest.httpMethod = "POST"
urlRequest.httpBody = """
{
    "model": "gpt-4o-mini",
    "messages": [
        {"role": "user", "content": "Why is the sky blue?"}
    ],
    "stream": true
}
""".data(using: .utf8)!

let eventSource = EventSource(mode: .dataOnly)
let dataTask = await eventSource.dataTask(for: urlRequest)

var response: String = ""

for await event in await dataTask.events() {
    switch event {
    case .event(let event):
        if let data = eventDevent.data?.data(using: .utf8) {
            let chunk = try? JSONDecoder().decode(ChatCompletionChunk.self, from: data)
            let string = chunk?.choices.first?.delta.content ?? ""
            response += string
        }
    default:
        break
    }
}

print(response)

兼容性

依赖

无依赖。

贡献

欢迎随时贡献! 有关更多详细信息,请参见 CONTRIBUTING.md

许可证

EventSource 在 MIT 许可证下发布。 有关更多信息,请参见 LICENSE