Как разрешить адреса и информацию о портах из случая перечисления NWEndpoint.service (если возможно)
В настоящее время я использую NetServiceBrowser
найти службы Bonjour и разрешить соответствующие адреса и порт.
Пытаясь упростить свой код, я наткнулся на NWBrowser
который, кажется, предоставляет очень простой интерфейс для работы с обнаружением Bonjour.
Тем не менее browseResultsChangedHandler
отправляет обратно результаты и изменения, которые содержат конечную точку enum case service
. Я пытаюсь получить информацию об адресе и порте из результатов, но, похоже,NWEndpoint
должен быть перечислимого типа.hostPort.
В идеале я бы использовал конечную точку для подключения к серверам, используя NWConnection
однако я использую другую библиотеку, которая не обрабатывает NWEndpoint
прямо.
Существуют ли (простые) способы получения адресов и информации о портах из NWEndpoint.service
результат?
import Foundation
import Network
let browser = NWBrowser(for: .bonjour(type: "_http._tcp", domain: ""), using: NWParameters())
browser.browseResultsChangedHandler = { (results, changes) in
print("Results:")
for result in results
{
if case .service(let service) = result.endpoint
{
debugPrint(service)
}
else
{
assert(false, "This nevers gets executed")
}
}
print("Changes:")
for change in changes
{
if case .added(let added) = change
{
if case .service(let service) = added.endpoint
{
debugPrint(service)
}
else
{
assert(false, "This nevers gets executed")
}
}
}
}
browser.start(queue: DispatchQueue.main)
sleep(3)
1 ответ
Это возможно.
Во-первых, вы не должны пытаться получить хост и порт службы до тех пор, пока пользователь не решит подключиться к ней - в большинстве приложений вы должны хранить только ссылку на объект службы, поскольку Bonjour позволяет хосту и порту службы подключаться к ней. изменять. Из концепции Bonjour:
Кроме того, службы не привязаны к конкретным IP-адресам или даже именам хостов. […] Если клиенты сохраняют имя хоста (как в большинстве случаев они хранят сейчас), они не смогут подключиться, если служба переместится на другой хост.
Bonjour придерживается сервис-ориентированного взгляда. Запросы выполняются в соответствии с типом необходимых услуг, а не с хостами, которые их предоставляют. Приложения хранят имена экземпляров службы, а не адреса, поэтому, если IP-адрес, номер порта или даже имя хоста изменились, приложение все равно может подключиться. Сосредоточение внимания на услугах, а не на устройствах, делает работу пользователя в Интернете более полезной и беспроблемной.
Это снижает шум DNS в вашей сети и является основой конструкции Bonjour. Это означает, что все мои следующие предложения не должны происходить в вашем
browseResultsChangedHandler
.
Официально рекомендуемый способ использования
NWBrowser
кажется, чтобы открыть
NWConnection
к службе и используйте это вместо извлечения адреса и порта и подключения вручную. Вы можете открыть соединение, и сетевая структура будет обрабатывать разрешение фактического хоста / порта и подключение к службе.
let connection = NWConnection(to: service.endpoint, using: .tcp)
connection.stateUpdateHandler = { state in
switch state {
case .ready:
if let innerEndpoint = connection.currentPath?.remoteEndpoint,
case .hostPort(let host, let port) = innerEndpoint {
print("Connected to", "\(host):\(port)") // Here, I have the host/port information
}
default:
break
}
}
connection.start(queue: .global())
Если вы не можете использовать это соединение с сетевой структурой, я предполагаю, что вы могли бы затем закрыть соединение (возможно, вам нужно подождать, пока TCP перестанет использовать порт) и использовать его в своих целях.
Вы также можете использовать устаревший NetService
api для разрешения службы (хотя я лично не получил это для работы с экземпляром, созданным вручную) или DNSServiceResolve
.
В есть гораздо больше информации от официального представителя этой ветке форума разработчиков AppleApple.