Nguon: Microsoft Learn · .NET 8.0

ASP.NET Core SignalR Swift client (Máy khách Swift)

Nguồn: ASP.NET Core SignalR Swift client

SignalR Swift là thư viện máy khách (client library) để kết nối với máy chủ SignalR từ các ứng dụng Swift. Tài liệu này cung cấp tổng quan về cách cài đặt client, thiết lập kết nối, xử lý lệnh gọi từ máy chủ đến client, gọi phương thức máy chủ, làm việc với phản hồi streaming, và cấu hình kết nối lại tự động cùng các tùy chọn khác.

Cài đặt gói SignalR client

Thư viện SignalR Swift client được phân phối dưới dạng gói Swift. Bạn có thể thêm nó vào dự án bằng Swift Package Manager.

Yêu cầu

Cài đặt bằng Swift Package Manager

Thêm gói SignalR Swift làm dependency trong tệp Package.swift:

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")])
    ]
)

Sau khi thêm dependency, nhập thư viện vào code Swift của bạn:

swift
import SignalRClient

Kết nối đến hub

Để thiết lập kết nối, tạo một HubConnectionBuilder và cấu hình nó với URL của máy chủ SignalR bằng phương thức withUrl(). Sau khi kết nối được tạo, gọi start() để kết nối đến máy chủ:

swift
import SignalRClient

let connection = HubConnectionBuilder()
    .withUrl(url: "https://your-signalr-server")
    .build()

try await connection.start()

Gọi phương thức client từ hub

Để nhận tin nhắn từ máy chủ, đăng ký một handler bằng phương thức on. Phương thức on nhận tên phương thức hub và một closure sẽ được thực thi khi máy chủ gọi phương thức đó.

Trong ví dụ sau, tên phương thức là ReceiveMessage. Tên đối số là usermessage:

swift
await connection.on("ReceiveMessage") { (user: String, message: String) in
    print("\(user) says: \(message)")
}

Code trong connection.on chạy khi code phía máy chủ gọi nó bằng phương thức SendAsync:

csharp
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 xác định phương thức client nào cần gọi bằng cách khớp tên phương thức và các đối số được định nghĩa trong SendAsyncconnection.on.

Thực hành tốt nhất là gọi try await connection.start() trên HubConnection sau on. Điều này đảm bảo các handler được đăng ký trước khi nhận bất kỳ tin nhắn nào.

Gọi phương thức hub từ client

Swift client có thể gọi các phương thức hub trên máy chủ bằng phương thức invoke hoặc send của HubConnection. Phương thức invoke chờ phản hồi từ máy chủ và ném lỗi nếu lệnh gọi thất bại, trong khi phương thức send không chờ phản hồi.

Trong code sau, tên phương thức trên hub là SendMessage. Đối số thứ hai và thứ ba truyền vào invoke ánh xạ tới các đối số usermessage của phương thức hub:

swift
// 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")

Phương thức invoke trả về với giá trị trả về (nếu có) khi phương thức trên máy chủ trả về. Nếu phương thức trên máy chủ ném lỗi, hàm sẽ ném lỗi.

Ghi log (Logging)

Thư viện Swift client bao gồm một hệ thống ghi log nhẹ được thiết kế cho các ứng dụng Swift. Nó cung cấp cách có cấu trúc để ghi log tin nhắn ở các mức độ nghiêm trọng khác nhau, sử dụng log handler có thể tùy chỉnh. Trên nền tảng Apple, nó tận dụng os.Logger để ghi log hệ thống hiệu quả, trong khi trên các nền tảng khác, nó sử dụng đầu ra console tiêu chuẩn.

Mức log

Sử dụng HubConnectionBuilder().withLogLevel(LogLevel:) để đặt mức log. Tin nhắn được ghi log ở mức được chỉ định và cao hơn:

Kết quả client

Ngoài việc gọi phương thức máy chủ, máy chủ có thể gọi các phương thức trên client và chờ phản hồi. Để hỗ trợ điều này, định nghĩa một handler client trả về kết quả từ closure của nó:

swift
await connection.on("ClientResult") { (message: String) in
    return "client response"
}

Ví dụ, máy chủ có thể gọi phương thức ClientResult trên client và chờ giá trị trả về:

csharp
public class ChatHub : Hub
{
    public async Task TriggerClientResult()
    {
        var message = await Clients.Client(connectionId).InvokeAsync<string>("ClientResult");
    }
}

Làm việc với phản hồi streaming

Để nhận luồng dữ liệu từ máy chủ, sử dụng phương thức stream. Phương thức trả về một stream mà bạn có thể lặp qua bất đồng bộ:

swift
let streamResult: any StreamResult<String> = try await connection.stream(method: "StreamMethod")
for try await item in streamResult.stream {
    print("Received item: \(item)")
}

Xử lý kết nối bị mất

Kết nối lại tự động

SignalR Swift client hỗ trợ kết nối lại tự động. Để bật tính năng này, gọi withAutomaticReconnect() khi xây dựng kết nối. Kết nối lại tự động bị tắt theo mặc định.

swift
let connection = HubConnectionBuilder()
    .withUrl(url: "https://your-signalr-server")
    .withAutomaticReconnect()
    .build()

Khi không có tham số, withAutomaticReconnect() cấu hình client để chờ 0, 2, 10 và 30 giây tương ứng trước mỗi lần kết nối lại. Sau bốn lần thất bại, client ngừng thử kết nối lại.

Trước khi bắt đầu bất kỳ lần kết nối lại nào, HubConnection chuyển sang trạng thái Reconnecting và kích hoạt các callback onReconnecting.

Sau khi kết nối lại thành công, HubConnection chuyển sang trạng thái connected và kích hoạt các callback onReconnected.

Cách thông dụng để sử dụng onReconnectingonReconnected là đánh dấu các thay đổi trạng thái kết nối:

swift
connection.onReconnecting { error in
    // connection is disconnected because of error
}

connection.onReconnected {
    // connection is connected back
}

Cấu hình chiến lược kết nối lại tự động

Để tùy chỉnh hành vi kết nối lại, bạn có thể truyền một mảng số đại diện cho độ trễ tính bằng giây trước mỗi lần kết nối lại. Để kiểm soát chi tiết hơn, truyền một đối tượng tuân theo giao thức RetryPolicy.

Sử dụng mảng giá trị độ trễ

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

Sử dụng retry policy tùy chỉnh

Triển khai giao thức RetryPolicy để kiểm soát thời gian kết nối lại:

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

Cấu hình tùy chọn timeout và keep-alive

Bạn có thể tùy chỉnh cài đặt timeout và keep-alive của client thông qua HubConnectionBuilder:

Tùy chọnGiá trị mặc địnhMô tả
withKeepAliveInterval15 (giây)Xác định khoảng thời gian client gửi tin nhắn ping. Cài đặt này cho phép máy chủ phát hiện các ngắt kết nối cứng, chẳng hạn khi client rút phích cắm máy tính khỏi mạng. Gửi bất kỳ tin nhắn nào từ client sẽ đặt lại bộ đếm thời gian. Nếu client không gửi tin nhắn trong khoảng ClientTimeoutInterval được đặt trên máy chủ, máy chủ coi client đã ngắt kết nối.
withServerTimeout30 (giây)Xác định khoảng thời gian client chờ phản hồi từ máy chủ trước khi coi máy chủ đã ngắt kết nối.

Cấu hình transport (phương thức vận chuyển)

SignalR Swift client hỗ trợ ba loại transport: LongPolling, ServerSentEvents, và WebSockets. Theo mặc định, client sử dụng WebSockets nếu máy chủ hỗ trợ, và chuyển sang ServerSentEvents và LongPolling nếu không. Bạn có thể cấu hình client sử dụng một transport cụ thể bằng cách gọi withUrl(url:transport:) khi xây dựng kết nối.

swift
let connection = HubConnectionBuilder()
    .withUrl(url: "https://your-signalr-server", transport: .webSockets) // use websocket only
    .build()
swift
let connection = HubConnectionBuilder()
    .withUrl(url: "https://your-signalr-server", transport: [.webSockets, .serverSentEvents]) // use websockets and server sent events
    .build()