Bonjour/MYBonjourBrowser.m
changeset 31 1d6924779df7
parent 28 732576fa8a0d
child 45 8efb48eabd08
     1.1 --- a/Bonjour/MYBonjourBrowser.m	Mon Apr 27 09:03:56 2009 -0700
     1.2 +++ b/Bonjour/MYBonjourBrowser.m	Wed Apr 29 13:29:31 2009 -0700
     1.3 @@ -8,6 +8,7 @@
     1.4  
     1.5  #import "MYBonjourBrowser.h"
     1.6  #import "MYBonjourService.h"
     1.7 +#import "MYBonjourRegistration.h"
     1.8  #import "ExceptionUtils.h"
     1.9  #import "Test.h"
    1.10  #import "Logging.h"
    1.11 @@ -51,6 +52,8 @@
    1.12  - (void) dealloc
    1.13  {
    1.14      LogTo(Bonjour,@"DEALLOC BonjourBrowser");
    1.15 +    [_myRegistration cancel];
    1.16 +    [_myRegistration release];
    1.17      [_serviceType release];
    1.18      [_services release];
    1.19      [_addServices release];
    1.20 @@ -68,12 +71,12 @@
    1.21  }
    1.22  
    1.23  
    1.24 -- (DNSServiceRef) createServiceRef {
    1.25 -    DNSServiceRef serviceRef = NULL;
    1.26 -    self.error = DNSServiceBrowse(&serviceRef, 0, 0,
    1.27 -                                  _serviceType.UTF8String, NULL,
    1.28 -                                  &browseCallback, self);
    1.29 -    return serviceRef;
    1.30 +- (DNSServiceErrorType) createServiceRef: (DNSServiceRef*)sdRefPtr {
    1.31 +    return DNSServiceBrowse(sdRefPtr,
    1.32 +                            kDNSServiceFlagsShareConnection, 
    1.33 +                            0,
    1.34 +                            _serviceType.UTF8String, NULL,
    1.35 +                            &browseCallback, self);
    1.36  }
    1.37  
    1.38  
    1.39 @@ -93,8 +96,15 @@
    1.40                                                                 type: regtype
    1.41                                                               domain: domain
    1.42                                                            interface: interfaceIndex];
    1.43 +    if ([_myRegistration isSameAsService: service]) {
    1.44 +        // This is an echo of my own registration, so ignore it
    1.45 +        LogTo(Bonjour,@"%@ ignoring echo %@", self,service);
    1.46 +        [service release];
    1.47 +        return;
    1.48 +    }
    1.49      MYBonjourService *existingService = [_services member: service];
    1.50      if( existingService ) {
    1.51 +        // Use existing service object instead of creating a new one
    1.52          [service release];
    1.53          service = [existingService retain];
    1.54      }
    1.55 @@ -114,14 +124,17 @@
    1.56          [addTo addObject: service];
    1.57      [service release];
    1.58      
    1.59 -    // After a round of updates is done, do the update:
    1.60 -    if( ! (flags & kDNSServiceFlagsMoreComing) )
    1.61 -        [self _updateServiceList];
    1.62 +    // Schedule a (single) call to _updateServiceList:
    1.63 +    if (!_pendingUpdate) {
    1.64 +        [self performSelector: @selector(_updateServiceList) withObject: nil afterDelay: 0];
    1.65 +        _pendingUpdate = YES;
    1.66 +    }
    1.67  }
    1.68  
    1.69  
    1.70  - (void) _updateServiceList
    1.71  {
    1.72 +    _pendingUpdate = NO;
    1.73      if( _rmvServices.count ) {
    1.74          [self willChangeValueForKey: @"services" 
    1.75                      withSetMutation: NSKeyValueMinusSetMutation
    1.76 @@ -156,17 +169,30 @@
    1.77                              const char                          *replyDomain,
    1.78                              void                                *context)
    1.79  {
    1.80 +    MYBonjourBrowser *browser = context;
    1.81      @try{
    1.82          //LogTo(Bonjour,@"browseCallback (error=%i, name='%s')", errorCode,serviceName);
    1.83 -        if (errorCode)
    1.84 -            [(MYBonjourBrowser*)context priv_gotError: errorCode];
    1.85 -        else
    1.86 -            [(MYBonjourBrowser*)context priv_gotServiceName: [NSString stringWithUTF8String: serviceName]
    1.87 -                                                       type: [NSString stringWithUTF8String: regtype]
    1.88 -                                                     domain: [NSString stringWithUTF8String: replyDomain]
    1.89 -                                                  interface: interfaceIndex
    1.90 -                                                      flags: flags];
    1.91 +        if (!errorCode)
    1.92 +            [browser priv_gotServiceName: [NSString stringWithUTF8String: serviceName]
    1.93 +                                    type: [NSString stringWithUTF8String: regtype]
    1.94 +                                  domain: [NSString stringWithUTF8String: replyDomain]
    1.95 +                               interface: interfaceIndex
    1.96 +                                   flags: flags];
    1.97      }catchAndReport(@"Bonjour");
    1.98 +    [browser gotResponse: errorCode];
    1.99 +}
   1.100 +
   1.101 +
   1.102 +- (void) cancel {
   1.103 +    [_myRegistration stop];
   1.104 +    [super cancel];
   1.105 +}
   1.106 +
   1.107 +
   1.108 +- (MYBonjourRegistration *) myRegistration {
   1.109 +    if (!_myRegistration)
   1.110 +        _myRegistration = [[MYBonjourRegistration alloc] initWithServiceType: _serviceType port: 0];
   1.111 +    return _myRegistration;
   1.112  }
   1.113  
   1.114  
   1.115 @@ -198,6 +224,10 @@
   1.116          [_browser addObserver: self forKeyPath: @"services" options: NSKeyValueObservingOptionNew context: NULL];
   1.117          [_browser addObserver: self forKeyPath: @"browsing" options: NSKeyValueObservingOptionNew context: NULL];
   1.118          [_browser start];
   1.119 +        
   1.120 +        MYBonjourRegistration *myReg = _browser.myRegistration;
   1.121 +        myReg.port = 12346;
   1.122 +        Assert([myReg start]);
   1.123      }
   1.124      return self;
   1.125  }