NWListener疑问:能否直接发现applicationService类型的服务?
无法直接通过
.applicationService浏览NWListener服务的原因及解决方案 是的,你无法直接通过.applicationService类型来发现NWListener的服务。这是由applicationService的设计定位决定的:
.applicationService并不是用于服务发现的标识,它的作用是在已经通过Bonjour发现服务之后,作为连接阶段的协议标识符——用来区分同一Bonjour服务下的不同应用协议,或者确保连接到预期的应用实例。- 苹果TicTacToe示例的逻辑就是标准用法:用Bonjour完成服务发现,再用
applicationService指定具体的应用层协议。
你的代码问题分析
- 监听器端:仅设置
applicationService不会触发Bonjour广播,网络中无法感知到这个服务,所以浏览器找不到。另外你提到用.applicationService作为NWParameters会报"Network is down",是因为这个参数仅用于连接场景,不能用于监听配置。 - 浏览器端:用
.applicationService作为浏览类型本身就不符合设计预期,它无法扫描到任何网络中的服务,因为没有对应的广播源。
正确的实现方式
要实现服务发现+连接,需要结合Bonjour服务类型和applicationService:
监听器代码
let params = NWParameters.tcp let listener = try NWListener(using: params) // 通过Bonjour服务类型广播,同时附加applicationService作为连接标识 listener.service = NWListener.Service( bonjour: NWListener.BonjourService(name: "", type: "_myapp._tcp."), applicationService: "MyApp" ) listener.stateUpdateHandler = { state in print("listener state:", state) } listener.newConnectionHandler = { connection in // 验证连接的applicationService是否匹配 if connection.applicationService == "MyApp" { connection.start(queue: .main) // 后续处理连接逻辑 } } listener.start(queue: .main)
浏览器代码
let params = NWParameters.tcp // 用对应的Bonjour服务类型浏览网络中的服务 let browser = NWBrowser(for: .bonjour(type: "_myapp._tcp.", domain: nil), using: params) browser.stateUpdateHandler = { newState in print("browser:", newState) } browser.browseResultsChangedHandler = { results, changes in for result in results { // 建立连接时指定applicationService,确保匹配目标应用协议 let connection = result.endpoint.connection(using: params) connection.applicationService = "MyApp" connection.stateUpdateHandler = { connState in print("connection state:", connState) // 处理连接状态变化逻辑 } connection.start(queue: .main) } } browser.start(queue: .main)
关键逻辑说明
- Bonjour服务类型(如
_myapp._tcp.)是DNS-SD标准的服务广播标识,NWListener通过它在网络中发布服务,NWBrowser通过它扫描发现服务。 applicationService是连接层面的私有标识,不会被广播到网络,仅用于在连接建立时验证双方的应用协议一致性,避免连接到不匹配的服务实例。
内容的提问来源于stack exchange,提问作者alekop
相关产品推荐
相关产品推荐

