1
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
import Foundation
|
||||
|
||||
class SSEClient: NSObject {
|
||||
private var url: URL
|
||||
private var headers: [String: String]
|
||||
private var eventSourceTask: URLSessionDataTask?
|
||||
private var onMessageCallback: ((String) -> Void)?
|
||||
private var onOpenCallback: (() -> Void)?
|
||||
private var onErrorCallback: ((Error?) -> Void)?
|
||||
|
||||
init(url: URL, headers: [String: String] = [:]) {
|
||||
self.url = url
|
||||
self.headers = headers
|
||||
super.init()
|
||||
}
|
||||
|
||||
func onMessage(_ callback: @escaping (String) -> Void) {
|
||||
onMessageCallback = callback
|
||||
}
|
||||
|
||||
func onOpen(_ callback: @escaping () -> Void) {
|
||||
onOpenCallback = callback
|
||||
}
|
||||
|
||||
func onError(_ callback: @escaping (Error?) -> Void) {
|
||||
onErrorCallback = callback
|
||||
}
|
||||
|
||||
func start() {
|
||||
let session = URLSession(configuration: .default, delegate: self, delegateQueue: nil)
|
||||
|
||||
var request = URLRequest(url: url)
|
||||
// 添加默认的SSE头信息
|
||||
request.addValue("text/event-stream", forHTTPHeaderField: "Accept")
|
||||
request.addValue("no-cache", forHTTPHeaderField: "Cache-Control")
|
||||
|
||||
// 添加自定义头信息
|
||||
for (key, value) in headers {
|
||||
request.addValue(value, forHTTPHeaderField: key)
|
||||
}
|
||||
|
||||
eventSourceTask = session.dataTask(with: request)
|
||||
eventSourceTask?.resume()
|
||||
}
|
||||
|
||||
func stop() {
|
||||
eventSourceTask?.cancel()
|
||||
}
|
||||
}
|
||||
|
||||
extension SSEClient: URLSessionDataDelegate {
|
||||
func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) {
|
||||
guard let string = String(data: data, encoding: .utf8) else { return }
|
||||
let lines = string.components(separatedBy: .newlines)
|
||||
|
||||
for line in lines {
|
||||
if line.isEmpty { continue }
|
||||
if line.hasPrefix("data: ") {
|
||||
let message = line.replacingOccurrences(of: "data: ", with: "")
|
||||
onMessageCallback?(message)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive response: URLResponse, completionHandler: @escaping (URLSession.ResponseDisposition) -> Void) {
|
||||
completionHandler(.allow)
|
||||
onOpenCallback?()
|
||||
}
|
||||
|
||||
func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
|
||||
onErrorCallback?(error)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user