SignalR Swift 是用來從 Swift 應用程式連線到 SignalR 伺服器的用戶端連結庫。 本檔概述如何安裝用戶端、建立連線、處理伺服器對用戶端呼叫、叫用伺服器方法、處理串流回應,以及設定自動重新連線和其他選項。
安裝 SignalR 用戶端套件
SignalR Swift 用戶端連結庫會以 Swift 套件的形式傳遞。 您可以使用 Swift 套件管理員將它新增至專案。
需求
- 迅捷 >= 5.10
- macOS >= 11.0
- iOS >= 14
使用 Swift 套件管理員安裝
將 SignalR Swift 套件新增為 Package.swift 檔案中的相依性:
// swift-tools-version: 5.10
import PackageDescription
let package = Package(
name: "signalr-client-app",
dependencies: [
.package(url: "https://github.com/dotnet/signalr-client-swift", branch: "main")
],
targets: [
.executableTarget(name: "YourTargetName", dependencies: [.product(name: "SignalRClient", package: "signalr-client-swift")])
]
)
新增相依性之後,請在 Swift 程式代碼中匯入連結庫:
import SignalRClient
連線至樞紐
若要建立連線,請使用 HubConnectionBuilder 方法來建立 SignalR,並使用 withUrl() 伺服器的 URL 進行設定。 建置連線之後,請呼叫 start() 以連線到伺服器:
import SignalRClient
let connection = HubConnectionBuilder()
.withUrl(url: "https://your-signalr-server")
.build()
try await connection.start()
從中樞呼叫用戶端方法
若要從伺服器接收訊息,請使用 on 方法註冊處理程式。
on 方法會接收中樞方法的名稱和一個閉包,當伺服器呼叫該方法時執行該閉包。
在下文中,方法的名稱是 ReceiveMessage。 引數名稱為 user 和 message:
await connection.on("ReceiveMessage") { (user: String, message: String) in
print("\(user) says: \(message)")
}
connection.on 中的上述程式碼會在伺服器端程式碼使用 SendAsync 方法進行呼叫時執行:
using Microsoft.AspNetCore.SignalR;
namespace SignalRChat.Hubs;
public class ChatHub : Hub
{
public async Task SendMessage(string user, string message)
{
await Clients.All.SendAsync("ReceiveMessage", user, message);
}
}
SignalR 會比對 SendAsync 和 connection.on 中所定義的方法名稱和引數,來判斷要呼叫的用戶端方法。
最佳做法 是在 try await connection.start()之後於 HubConnection 上呼叫 on 方法。 這麼做可確保在收到任何訊息之前先註冊處理程序。
從客戶端呼叫集線器方法
Swift 用戶端可以使用 HubConnection 的 invoke 或 send 方法來叫用伺服器上的中樞方法。
invoke 方法會等候伺服器的回應,並在呼叫失敗時擲回錯誤,而 send 方法不會等候回應。
在下列程式代碼中,中樞上的方法名稱 SendMessage。 傳遞至 invoke 的第二個和第三個引數會對應至中樞方法的 user 和 message 引數:
// Using invoke, which waits for a response
try await connection.invoke(method: "SendMessage", arguments: "myUser", "Hello")
// Using send, which does not wait for a response
try await connection.send(method: "SendMessage", arguments: "myUser", "Hello")
當伺服器上的 方法傳回時,invoke 方法會傳回傳回值(如果有的話)。 如果伺服器上的 方法擲回錯誤,則函式會擲回錯誤。
伐木
Swift 用戶端連結庫包含專為 Swift 應用程式設計的輕量型記錄系統。 它提供了一種結構化的方法,藉由可自定義的日誌處理程式,以不同層級的嚴重性記錄訊息。 在 Apple 平臺上,它會利用 os.Logger 進行有效率的系統記錄,而在其他平臺上,它會回復為標準控制台輸出。
記錄等級
使用 HubConnectionBuilder().withLogLevel(LogLevel:) 來設定記錄層級。 訊息會以指定的記錄層級和更高層級來記錄:
-
LogLevel.debug:偵錯的實用詳細資訊。 -
LogLevel.information:一般應用程式訊息。 -
LogLevel.warning:潛在問題的警告。 -
LogLevel.error:需要立即注意的錯誤。
用戶端結果
除了叫用伺服器方法之外,伺服器還可以在用戶端上呼叫方法,並等候回應。 若要支援此功能,請定義客戶端處理程式,使能從其閉包傳回結果:
await connection.on("ClientResult") { (message: String) in
return "client response"
}
例如,伺服器可以在用戶端上叫用 ClientResult 方法,並等候傳回的值:
public class ChatHub : Hub
{
public async Task TriggerClientResult()
{
var message = await Clients.Client(connectionId).InvokeAsync<string>("ClientResult");
}
}
處理串流回應
若要從伺服器接收數據流,請使用 stream 方法。 方法會傳回您可以以異步方式逐一查看的數據流:
let streamResult: any StreamResult<String> = try await connection.stream(method: "StreamMethod")
for try await item in streamResult.stream {
print("Received item: \(item)")
}
處理遺失的連線
自動重新連線
SignalR Swift 用戶端支援自動重新連線。 若要啟用它,請在建置連線時呼叫withAutomaticReconnect()。 預設會停用自動重新連線。
let connection = HubConnectionBuilder()
.withUrl(url: "https://your-signalr-server")
.withAutomaticReconnect()
.build()
如果沒有參數,withAutomaticReconnect() 會分別將客戶端設定為在每次重新連線嘗試之前等候 0、2、10 和 30 秒。 四次嘗試失敗之後,用戶端會停止嘗試重新連線。
在開始任何重新連線嘗試之前,HubConnection 會轉換為 Reconnecting 狀態,並觸發其 onReconnecting 回調函數。
重新連線成功之後,HubConnection 會轉換成 connected 狀態,並觸發其 onReconnected 回呼。
使用 onReconnecting 與 onReconnected 的一般方法是標記連線狀態變更:
connection.onReconnecting { error in
// connection is disconnected because of error
}
connection.onReconnected {
// connection is connected back
}
在自動重新連線中設定策略
若要自訂重新連線行為,您可以傳遞一個數字陣列,用於表示每次重新連線嘗試前的延遲秒數。 如需更細微的控制,請傳遞符合 RetryPolicy 通訊協議的物件。
使用一組延遲值的陣列
let connection = HubConnectionBuilder()
.withUrl(url: "https://your-signalr-server")
.withAutomaticReconnect([0, 0, 1]) // Wait 0, 0, and 1 second before each reconnect attempt; stop after 3 attempts.
.build()
使用自定義重試原則
實作 RetryPolicy 通訊協定來控制重新連線時間:
// Define a custom retry policy
struct CustomRetryPolicy: RetryPolicy {
func nextRetryInterval(retryContext: RetryContext) -> TimeInterval? {
// For example, retry every 1 second indefinitely.
return 1
}
}
let connection = HubConnectionBuilder()
.withUrl(url: "https://your-signalr-server")
.withAutomaticReconnect(CustomRetryPolicy())
.build()
設定逾時和連線存活選項
您可以透過 HubConnectionBuilder 自訂用戶端的超時和保持連線設定:
| 選項 | 預設值 | 說明 |
|---|---|---|
| 保持存活間隔設定 | 15 (秒) | 決定客戶端傳送 Ping 訊息並直接在 HubConnectionBuilder 上設定的間隔。 此設定可讓伺服器偵測強制中斷連線的情況,例如用戶端拔除其電腦與網路的連線。 從客戶端傳送任何訊息會將定時器重設為間隔的開頭。 如果用戶端尚未在伺服器上設定的 ClientTimeoutInterval 中傳送訊息,伺服器就會將客戶端視為已中斷連線。 |
| 伺服器超時設置 | 30 (秒) | 判斷客戶端在考慮伺服器中斷連線之前,等候伺服器回應的間隔。 此設定會直接在 HubConnectionBuilder 上設定。 |
設定傳輸
SignalR Swift 用戶端支援三種傳輸:LongPolling、ServerSentEvents 和 WebSockets。 根據預設,如果伺服器支援 WebSockets,用戶端會使用 WebSockets,如果伺服器不支援,則會回復為 ServerSentEvents 和 LongPolling。 您可以藉由在建置連線時呼叫 withUrl(url:transport:),將客戶端設定為使用特定傳輸。
let connection = HubConnectionBuilder()
.withUrl(url: "https://your-signalr-server", transport: .webSockets) // use websocket only
.build()
let connection = HubConnectionBuilder()
.withUrl(url: "https://your-signalr-server", transport: [.webSockets, .serverSentEvents]) // use websockets and server sent events
.build()