EventSource

EventSource

使用 NSURLSession 在 Swift 上编写的 SSE 客户端。

Build Status codecov.io codecov.io

摘要

这是一个使用 Swift 编写的 EventSource 实现,遵循 W3C EventSource 文档。如果缺少某些内容或不完全正确,请提出 issue,我会处理它!

如果您喜欢这个库,请给我们一个 ★。这有助于我们保持对维护的参与!

从 2.2.1 版本到 3.0 版本的更改

我花了一些时间审查了 github 上所有 fork、pull request 和 issue。我发现的主要变化和抱怨与连接和 Last-Event-Id 处理有关。

此版本中的更改是

如何使用它?

在存储库中有一个简单的工作示例。查看 ViewController.swift 以了解如何使用它。

同样,在 sse-server 文件夹中,您会找到一个非常简单的 node.js 服务器来测试该库。要运行服务器,您只需要

安装

Cocoapods

  1. 在您的 Podfile 中包含 EventSource: pod 'IKEventSource'

  2. 导入框架

import IKEventSource

Carthage

  1. 在您的 Cartfile 中包含 EventSource:github "inaka/EventSource"

  2. 导入框架

import IKEventSource

有关更多参考,请参见 Carthage 的文档

Swift Package Manager

  1. 在您的 Package.swift 中包含 EventSource:github "inaka/EventSource"
import PackageDescription

let package = Package(
dependencies: [
    .package(url: "https://github.com/inaka/EventSource.git", .branch("master"))
])
  1. 导入框架
import IKEventSource

Swift API

/// RetryTime: This can be changed remotly if the server sends an event `retry:`
var retryTime: Int { get }

/// URL where EventSource will listen for events.
var url: URL { get }

/// The last event id received from server. This id is neccesary to keep track of the last event-id received to avoid
/// receiving duplicate events after a reconnection.
var lastEventId: String? { get }

/// Current state of EventSource
var readyState: EventSourceState { get }

/// Method used to connect to server. It can receive an optional lastEventId indicating the Last-Event-ID
///
/// - Parameter lastEventId: optional value that is going to be added on the request header to server.
func connect(lastEventId: String?)

/// Method used to disconnect from server.
func disconnect()

/// Returns the list of event names that we are currently listening for.
///
/// - Returns: List of event names.
func events() -> [String]

/// Callback called when EventSource has successfully connected to the server.
///
/// - Parameter onOpenCallback: callback
func onOpen(_ onOpenCallback: @escaping (() -> Void))

/// Callback called once EventSource has disconnected from server. This can happen for multiple reasons.
/// The server could have requested the disconnection or maybe a network layer error, wrong URL or any other
/// error. The callback receives as parameters the status code of the disconnection, if we should reconnect or not
/// following event source rules and finally the network layer error if any. All this information is more than
/// enought for you to take a decition if you should reconnect or not.
/// - Parameter onOpenCallback: callback
func onComplete(_ onComplete: @escaping ((Int?, Bool?, NSError?) -> Void))

/// This callback is called everytime an event with name "message" or no name is received.
func onMessage(_ onMessageCallback: @escaping ((_ id: String?, _ event: String?, _ data: String?) -> Void))

/// Add an event handler for an specific event name.
///
/// - Parameters:
///   - event: name of the event to receive
///   - handler: this handler will be called everytime an event is received with this event-name
func addEventListener(_ event: String,
                      handler: @escaping ((_ id: String?, _ event: String?, _ data: String?) -> Void))

/// Remove an event handler for the event-name
///
/// - Parameter event: name of the listener to be remove from event source.
func removeEventListener(_ event: String)

例子


事件:

id: event-id
event: event-name
data: event-data

调用

eventSource.addEventListener("event-name") { (id, event, data) in
  // Here you get an event 'event-name'
}

事件:

id: event-id
data: event-data
data: event-data

调用

eventSource.onMessage { (id, event, data) in
  // Here you get an event without event name!
}

事件:

id: event-id
data: event-data-1
data: event-data-2
data: event-data-3

调用

eventSource.onMessage { (id, event, data) in
  // Here you get an event without event name!
  // data: event-data-1\nevent-data-2\nevent-data-3
}

事件:

:heartbeat

调用

nothing it's a comment

实时示例

这是应用程序附带的示例。如果您运行服务器并运行应用程序,您将能够看到此示例的直播。移动的盒子只是为了表明一切都在后台工作,并且主线程性能没有下降。(gif 看起来很糟糕,但是如果您单击图像,您将被带到 gfycat 版本的 gif,它运行得更流畅)

Sample

贡献者

感谢所有贡献者指出缺失的东西或问题并修复它们或提出问题!!

联系我们

如果您在使用此库时发现任何 bug 或有 问题,请在此 repo 中提出 issue(或 pull request :))。

请提供您遇到的问题的示例。如果事件未正确解析,请提供示例事件。