Обнаружение клиента, разъединяющегося с UDP, используя Network.framework - PullRequest
0 голосов
/ 26 января 2019

Я пытаюсь определить, когда 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 Ответ

0 голосов
/ 06 февраля 2019

UDP-сервер не получает через сеть информации о том, был ли UDP-клиент отключен или отключен, если, возможно, клиент явно не отправляет какое-то дополнительное сообщение (через UDP, TCP или другой боковой канал) относительно своего состояния отключения. , Поэтому нет ничего, что могло бы изменить состояние NWConnection (кроме, возможно, какой-то проблемы с самим сервером).

Возможно, сервер может отключиться после некоторого согласованного или согласованного времени ожидания без какой-либо активности. Или количество пакетов, байтов данных. И т.д. И закройте само соединение.

...