Bonjour是一种zero configuration networking。
Publishing a Bonjour service
Bonjour allows for the discovery of network devices and services on an IP network without acentralized server.
这里publish service用到的是NSNetService,这里发出请求需要异步,NSNetwork使用delegate来处理service publication的通知,一个代理可以处理多个service
一开始定义了三个properties
@property int status;
@property (strong, nonatomic) NSNetService *service;
@property (retain, nonatomic) NSString *publishedName;
status表示Bonjour publication service 的状态,service就是要发布的对象,publishName代表发布的服务器的名字,除非手动更改名字( publishWithOptions: )在网络发生冲突的时候会进行rename。
如果想要这个类(BonjourPublishService)能够处理多个service,更改service为NSMutableDictionary,key就是publishName
-(void)startServiceOfType:(NSString *)type andPort:(int)port;
-(void)stopService;
接下来就是实现这个类
-(void)startServiceOfType:(NSString *)type andPort:(int)port {
self.status = BONJOURPUBLISHSTOPPED;
self.service = [[NSNetService alloc] initWithDomain:@""
type:type name:@"" port:port];
if (self.service) {
[self.service setDelegate:self];
[self.service publish];
}
else {
[[NSNotificationCenter defaultCenter]
postNotificationName:BONJOURNOTIFICATIONSTOP object:nil];
} }
这个方法就是用来publish service,有两个参数
type:这里指的是service的type,是一个字符串类型,既包含application layer type也包含transport protocol,格式是_{protocol}._{transport}例如_SFTP._tcp
port:就是端口
创建NSNetService所用到的方法initWithDomain:type:name:port其中的四个参数
domain:@""表示默认
type:service type,就是之前的那个参数type
name:advertise service用到的name,这里用@""代表用device的name来替代,除非本地网络有冲突不会重命名
port:端口
service不为空就设置代理并且发布。如果想disable the renaming of the service,调用publishWithOptions:NSNetServiceNoAutoRename
接下来是stopService
<span style="font-size:14px;">-(void)stopService {
[self.service stop];
[[NSNotificationCenter defaultCenter]
postNotificationName:BONJOURNOTIFICATIONSTOP
object:nil];
}</span>
没什么特别,接下来是NSNetService 的代理设定
-(void)netServiceWillPublish:(NSNetService *)sender {
self.status = BONJOURPUBLISHSTOPPED;
}
-(void)netServiceDidPublish:(NSNetService *)sender {
self.status = BONJOURPUBLISHSTARTED;
self.publishedName = sender.name;
[[NSNotificationCenter defaultCenter]
postNotificationName:BONJOURNOTIFICATIONSTART
object:nil];
}
-(void)netService:(NSNetService *)sender
didNotPublish:(NSDictionary *)errorDict {
self.status = BONJOURPUBLISHSTOPPED;
[[NSNotificationCenter defaultCenter]
postNotificationName:BONJOURNOTIFICATIONSTOP
object:nil];
}
-(void)netServiceDidStop:(NSNetService *)sender {
self.status = BONJOURPUBLISHSTOPPED;
[[NSNotificationCenter defaultCenter]
postNotificationName:BONJOURNOTIFICATIONSTOP
object:nil];
}
Discovering a Bonjour service
这个部分就是找到刚到发布的service,用到的是NSNetServiceBrowser类,在处理service discovery上也是异步
<span style="font-size:14px;"> @property int status;
@property (strong, nonatomic) NSNetServiceBrowser *serviceBrowser;
@property (strong, nonatomic) NSMutableArray *services;
-(void)startBrowsingForType:(NSString *)type;
-(void)stopBrowsing;</span>
services是用来装发现的所有service
<span style="font-size:14px;">-(void)startBrowsingForType:(NSString *)type;
-(void)stopBrowsing;</span><span style="font-size:12px;">
</span>
接下来是实现部分
首先进行了初始化init,没什么特别的
-(void)startBrowsingForType:(NSString *)type {
self.serviceBrowser = [[NSNetServiceBrowser alloc] init];
[self.serviceBrowser setDelegate:self];
[self.serviceBrowser searchForServicesOfType:type
inDomain:@""];
self.status = BONJOURBROWSERSEARCHING;
}
domain这是设置为@""是指local domain
-(void)stopBrowsing {
[self.serviceBrowser stop];
[self.services removeAllObjects];
}
接下来是代理方面
-(void)netServiceBrowserWillSearch:(NSNetServiceBrowser *)
aNetServiceBrowser {
self.status = BONJOURBROWSERSEARCHING;
[self changeNotification];
}
-(void)netServiceBrowserDidStopSearch:(NSNetServiceBrowser *)
aNetServiceBrowser {
self.status = BONJOURBROWSERSTOPPED;
[self changeNotification];
}
-(void)netServiceBrowser:(NSNetServiceBrowser *)aNetServiceBrowser
didNotSearch:(NSDictionary *)errorDict {
self.status = BONJOURBROWSERSTOPPED;
[self changeNotification];
}
-(void)netServiceBrowser:(NSNetServiceBrowser *)aNetServiceBrowser
didFindService:(NSNetService *)aNetService moreComing:(BOOL)
moreComing {
[self.services addObject:aNetService];
if (!moreComing)
[self changeNotification];
}
-(void)netServiceBrowser:(NSNetServiceBrowser *)aNetServiceBrowser
didRemoveService:(NSNetService *)aNetService moreComing:(BOOL)
moreComing {
[self.services removeObject:aNetService];
if (!moreComing)
[self changeNotification];
}
-(void)changeNotification {
[[NSNotificationCenter defaultCenter]
postNotificationName:BONJOURBROWSERNOTIFICATION
object:nil];
}
并没有什么特别
Resolving a Bonjour service
在学会了用NSNetService发布以及用NSNetServiceBrowser找到service后接下来就是解析NSNetService用来连接了
resolve得到的是IP地址/host name 以及端口,在resolve后可以存储,也可以直接连接,推荐直接连接,因为IP地址可能会变化
<span style="font-size:14px;"> -(void)resolveService:(NSNetService *)service {
[service setDelegate:self];
[service resolveWithTimeout:5.0];
}
-(void)netServiceDidResolveAddress:(NSNetService *)sender {
NSArray *addresses = sender.addresses;
// Use hostname and port combination if you are saving the
connection information
// NSString *hostname = sender.hostName;
// int port = sender.port;
[[NSNotificationCenter defaultCenter]
postNotificationName:BONJOURRESOLVERNOTIFICATION
object:addresses];
}
-(void)netService:(NSNetService *)sender
didNotResolve:(NSDictionary *)errorDict {
[[NSNotificationCenter defaultCenter] postNotificationName:BON
JOURRESOLVERNOTIFICATION object:nil];
}</span>
准备工作都做好了下一篇就进入正题了