Обнаружение клиента, разъединяющегося с UDP, используя Network.framework
Я пытаюсь определить, когда UDP-клиент перестает отправлять пакеты на сервер при использовании Network.framework
Я построил небольшой пример, который демонстрирует, что сервер не может изменить состояние на .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?
в конце концов)
Поэтому я не уверен, как определить, когда клиент прекращает отправку пакетов при использовании UDP-сервера на Network.framework. Как мне найти "отключенных" клиентов?
1 ответ
UDP-сервер не получает через сеть информации о том, был ли UDP-клиент отключен или отсутствует, если, возможно, клиент явно не отправляет какое-то дополнительное сообщение (через UDP, TCP или другой боковой канал) о своем состоянии разъединения. Поэтому нет ничего, что могло бы изменить состояние NWConnection (кроме, возможно, какой-то проблемы с самим сервером).
Возможно, сервер может отключиться после некоторого согласованного или согласованного времени ожидания без какой-либо активности. Или количество пакетов, байтов данных. И т.д. И закрой саму связь.