共用方式為


ASP.NET Core SignalR Swift 用戶端

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。 引數名稱為 usermessage

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 會比對 SendAsyncconnection.on 中所定義的方法名稱和引數,來判斷要呼叫的用戶端方法。

最佳做法 是在 try await connection.start()之後於 HubConnection 上呼叫 on 方法。 這麼做可確保在收到任何訊息之前先註冊處理程序。

從客戶端呼叫集線器方法

Swift 用戶端可以使用 HubConnection 的 invokesend 方法來叫用伺服器上的中樞方法。 invoke 方法會等候伺服器的回應,並在呼叫失敗時擲回錯誤,而 send 方法不會等候回應。

在下列程式代碼中,中樞上的方法名稱 SendMessage。 傳遞至 invoke 的第二個和第三個引數會對應至中樞方法的 usermessage 引數:

// 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 回呼。

使用 onReconnectingonReconnected 的一般方法是標記連線狀態變更:

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()

其他資源