使用 Network.framework 检测客户端与 UDP 断开连接
Detecting a client disconnecting with UDP using Network.framework
我正在尝试确定在使用 Network.framework
时 UDP 客户端何时停止向服务器发送数据包
我构建了一个小示例,演示当客户端的连接被取消时服务器无法将状态更改为 .cancelled
。
示例客户:
import Foundation
import Network
func sendMessage(on connection: NWConnection) {
connection.send(content: "hello".data(using: .utf8), completion: .contentProcessed({error in
if let error = error {
print("error while sending hello: \(error)")
return
}
connection.receiveMessage {data, context, isComplete, error in
if let error = error {
print("error while receiving reply: \(error)")
return
}
connection.cancel()
}
}))
}
var connection: NWConnection = {
let connection = NWConnection(
to: .service(
name: "Hello",
type: "_test._udp",
domain: "local",
interface: nil
),
using: .udp
)
connection.stateUpdateHandler = {newState in
switch newState {
case .ready:
sendMessage(on: connection)
case .failed(let error):
print("client failed with error: \(error)")
case .cancelled:
print("Cancelled connection")
default:
break
}
}
return connection
}()
connection.start(queue: DispatchQueue(label: "test"))
RunLoop.main.run()
示例服务器:
import Foundation
import Network
func receive(on connection: NWConnection) {
connection.receiveMessage { (data, context, isComplete, error) in
if let error = error {
print(error)
return
}
connection.send(content: "world".data(using: .utf8), completion: .contentProcessed({error in
if let error = error {
print("error while sending data: \(error)")
return
}
}))
receive(on: connection)
}
}
var listener: NWListener = {
let listener = try! NWListener(using: .udp)
listener.service = NWListener.Service(name: "Hello", type: "_test._udp", domain: nil, txtRecord: nil)
listener.newConnectionHandler = {newConnection in
newConnection.stateUpdateHandler = {newState in
switch newState {
case .ready:
receive(on: newConnection)
case .failed(let error):
print("client failed with error: \(error)")
case .cancelled:
print("Cancelled connection")
default:
break
}
}
newConnection.start(queue: DispatchQueue(label: "new client"))
}
return listener
}()
listener.start(queue: DispatchQueue(label: "test"))
RunLoop.main.run()
当运行客户端,而服务器运行时,客户端发送和接收一个数据包,然后被取消。客户端打印 Connection cancelled
。但是,服务器上 NWConnection 的状态不会改变,并且 connection.receiveMessage
当没有数据可从客户端读取时静默失败。
我希望服务器连接的状态发生变化,或者 receiveMessage
在没有数据存在的情况下调用其完成处理程序(data
毕竟是 Data?
)
因此,我不确定在 Network.framework 上使用 UDP 服务器时如何检测客户端何时停止发送数据包。我应该如何检测 "disconnected" 客户端?
UDP 服务器无法通过网络获取有关 UDP 客户端是否已断开连接或离开的信息,除非客户端可能明确发送某种附加消息(通过 UDP、TCP 或其他侧通道)关于其断开状态。所以没有什么可以改变 NWConnection 状态(除了服务器本身的某种问题)。
也许服务器可以假设在某个商定或协商的超时时间过去后断开连接,而没有某种 activity。或者数据包的数量,数据的字节数。等等。然后关闭连接本身。
我正在尝试确定在使用 Network.framework
时 UDP 客户端何时停止向服务器发送数据包我构建了一个小示例,演示当客户端的连接被取消时服务器无法将状态更改为 .cancelled
。
示例客户:
import Foundation
import Network
func sendMessage(on connection: NWConnection) {
connection.send(content: "hello".data(using: .utf8), completion: .contentProcessed({error in
if let error = error {
print("error while sending hello: \(error)")
return
}
connection.receiveMessage {data, context, isComplete, error in
if let error = error {
print("error while receiving reply: \(error)")
return
}
connection.cancel()
}
}))
}
var connection: NWConnection = {
let connection = NWConnection(
to: .service(
name: "Hello",
type: "_test._udp",
domain: "local",
interface: nil
),
using: .udp
)
connection.stateUpdateHandler = {newState in
switch newState {
case .ready:
sendMessage(on: connection)
case .failed(let error):
print("client failed with error: \(error)")
case .cancelled:
print("Cancelled connection")
default:
break
}
}
return connection
}()
connection.start(queue: DispatchQueue(label: "test"))
RunLoop.main.run()
示例服务器:
import Foundation
import Network
func receive(on connection: NWConnection) {
connection.receiveMessage { (data, context, isComplete, error) in
if let error = error {
print(error)
return
}
connection.send(content: "world".data(using: .utf8), completion: .contentProcessed({error in
if let error = error {
print("error while sending data: \(error)")
return
}
}))
receive(on: connection)
}
}
var listener: NWListener = {
let listener = try! NWListener(using: .udp)
listener.service = NWListener.Service(name: "Hello", type: "_test._udp", domain: nil, txtRecord: nil)
listener.newConnectionHandler = {newConnection in
newConnection.stateUpdateHandler = {newState in
switch newState {
case .ready:
receive(on: newConnection)
case .failed(let error):
print("client failed with error: \(error)")
case .cancelled:
print("Cancelled connection")
default:
break
}
}
newConnection.start(queue: DispatchQueue(label: "new client"))
}
return listener
}()
listener.start(queue: DispatchQueue(label: "test"))
RunLoop.main.run()
当运行客户端,而服务器运行时,客户端发送和接收一个数据包,然后被取消。客户端打印 Connection cancelled
。但是,服务器上 NWConnection 的状态不会改变,并且 connection.receiveMessage
当没有数据可从客户端读取时静默失败。
我希望服务器连接的状态发生变化,或者 receiveMessage
在没有数据存在的情况下调用其完成处理程序(data
毕竟是 Data?
)
因此,我不确定在 Network.framework 上使用 UDP 服务器时如何检测客户端何时停止发送数据包。我应该如何检测 "disconnected" 客户端?
UDP 服务器无法通过网络获取有关 UDP 客户端是否已断开连接或离开的信息,除非客户端可能明确发送某种附加消息(通过 UDP、TCP 或其他侧通道)关于其断开状态。所以没有什么可以改变 NWConnection 状态(除了服务器本身的某种问题)。
也许服务器可以假设在某个商定或协商的超时时间过去后断开连接,而没有某种 activity。或者数据包的数量,数据的字节数。等等。然后关闭连接本身。