SignalR Swift 是用于从 Swift 应用程序连接到 SignalR 服务器的客户端库。 本文档概述了如何安装客户端、建立连接、处理服务器到客户端调用、调用服务器方法、处理流式处理响应以及配置自动重新连接和其他选项。
SignalR安装客户端包
SignalR Swift 客户端库以 Swift 包的形式交付。 可以使用 Swift 包管理器将其添加到项目中。
要求
- Swift >= 5.10
- macOS >= 11.0
- iOS >= 14
使用 Swift 包管理器进行安装
在你的 Package.swift
文件中将 SignalR 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
并使用 withUrl()
方法为其配置一个 SignalR 服务器 URL。 生成连接后,调用 start()
以连接到服务器:
import SignalRClient
let connection = HubConnectionBuilder()
.withUrl(url: "https://your-signalr-server")
.build()
try await connection.start()
从中心调用客户端方法
若要从服务器接收消息,请使用 on
该方法注册处理程序。 on
方法需要 Hub 方法的名称和一个闭包,当服务器调用该方法时,这个闭包将被执行。
以下方法的名称是 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
中定义的方法名称和参数,来确定要调用的客户端方法。
最佳做法是在on
之后在HubConnection
上调用try await connection.start()
方法。 这样做可确保在接收任何消息之前注册处理程序。
从客户端调用中心方法
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 客户端支持自动重新连接。 若要启用它,在生成连接时使用AutomaticReconnect()进行调用。 默认情况下禁用自动重新连接。
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 自定义客户端的超时和保持连接设置:
选项 | 默认值 | 说明 |
---|---|---|
withKeepAliveInterval | 15 (秒) | 确定客户端发送 ping 消息的间隔,并直接在 HubConnectionBuilder 上设置。 使用此设置,服务器可以检测强行断开连接的情况,例如客户断开其计算机的网络连接。 从客户端发送任何消息会将计时器重置为间隔的开始。 如果客户端在服务器设置的 ClientTimeoutInterval 内未发送消息,服务器会认为客户端已断开连接。 |
withServerTimeout | 30 (秒) | 确定客户端在考虑服务器断开连接之前等待服务器响应的间隔。 此设置直接在 HubConnectionBuilder 上设置。 |
配置传输
SignalR Swift 客户端支持三种传输:LongPolling、ServerSentEvents 和 WebSocket。 默认情况下,如果服务器支持 WebSocket,客户端将使用 WebSocket,如果服务器不支持,则回退到 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()