BLIP/Demo/BLIPEchoClient.m
author Jens Alfke <jens@mooseyard.com>
Sun May 25 12:33:50 2008 -0700 (2008-05-25)
changeset 6 bceeeabb8c34
parent 3 76f302097a75
child 7 5936db2c1987
permissions -rw-r--r--
First public release.
     1 //
     2 //  BLIPEchoClient.m
     3 //  MYNetwork
     4 //
     5 //  Created by Jens Alfke on 5/24/08.
     6 //  Copyright 2008 Jens Alfke. All rights reserved.
     7 //  Adapted from Apple sample code "CocoaEcho":
     8 //  http://developer.apple.com/samplecode/CocoaEcho/index.html
     9 //
    10 
    11 #import "BLIPEchoClient.h"
    12 #import "BLIP.h"
    13 #import "IPAddress.h"
    14 #import "Target.h"
    15 
    16 
    17 @implementation BLIPEchoClient
    18 
    19 @synthesize serviceList=_serviceList;
    20 
    21 - (void)awakeFromNib 
    22 {
    23     _serviceBrowser = [[NSNetServiceBrowser alloc] init];
    24     _serviceList = [[NSMutableArray alloc] init];
    25     [_serviceBrowser setDelegate:self];
    26     
    27     [_serviceBrowser searchForServicesOfType:@"_blipecho._tcp." inDomain:@""];
    28 }
    29 
    30 #pragma mark -
    31 #pragma mark BLIPConnection support
    32 
    33 /* Opens a BLIP connection to the given address. */
    34 - (void)openConnection: (IPAddress*)address 
    35 {
    36     _connection = [[BLIPConnection alloc] initToAddress: address];
    37     [_connection open];
    38 }
    39 
    40 /* Closes the currently open BLIP connection. */
    41 - (void)closeConnection
    42 {
    43     [_connection close];
    44     [_connection release];
    45     _connection = nil;
    46 }
    47 
    48 #pragma mark -
    49 #pragma mark NSNetServiceBrowser delegate methods
    50 
    51 // We broadcast the willChangeValueForKey: and didChangeValueForKey: for the NSTableView binding to work.
    52 
    53 - (void)netServiceBrowser:(NSNetServiceBrowser *)aNetServiceBrowser didFindService:(NSNetService *)aNetService moreComing:(BOOL)moreComing {
    54     if (![_serviceList containsObject:aNetService]) {
    55         [self willChangeValueForKey:@"serviceList"];
    56         [_serviceList addObject:aNetService];
    57         [self didChangeValueForKey:@"serviceList"];
    58     }
    59 }
    60 
    61 - (void)netServiceBrowser:(NSNetServiceBrowser *)aNetServiceBrowser didRemoveService:(NSNetService *)aNetService moreComing:(BOOL)moreComing {
    62     if ([_serviceList containsObject:aNetService]) {
    63         [self willChangeValueForKey:@"serviceList"];
    64         [_serviceList removeObject:aNetService];
    65         [self didChangeValueForKey:@"serviceList"];
    66     }
    67 }
    68 
    69 #pragma mark -
    70 #pragma mark NSNetService delegate methods
    71 
    72 /* Stop any current Bonjour address resolution */
    73 - (void)stopResolving
    74 {
    75     if( _resolvingService ) {
    76         _resolvingService.delegate = nil;
    77         [_resolvingService stop];
    78         [_resolvingService release];
    79         _resolvingService = nil;
    80     }
    81 }    
    82 
    83 /* Ask Bonjour to resolve (look up) the IP address of the given service. */
    84 - (void)startResolving: (NSNetService*)service
    85 {
    86     [self stopResolving];
    87     _resolvingService = [service retain];
    88     _resolvingService.delegate = self;
    89     [_resolvingService resolveWithTimeout: 5.0];
    90     
    91 }
    92 
    93 /* NSNetService delegate method that will be called when address resolution finishes. */
    94 - (void)netServiceDidResolveAddress:(NSNetService *)sender
    95 {
    96     if( sender == _resolvingService ) {
    97         // Get the first address, which is an NSData containing a struct sockaddr:
    98         NSArray *addresses = _resolvingService.addresses;
    99         if( addresses.count > 0 ) {
   100             NSData *addressData = [addresses objectAtIndex: 0];
   101             IPAddress *address = [[IPAddress alloc] initWithSockAddr: addressData.bytes];
   102             [self openConnection: address];
   103             [address release];
   104         }
   105         [self stopResolving];
   106     }
   107 }
   108 
   109 #pragma mark -
   110 #pragma mark GUI action methods
   111 
   112 - (IBAction)serverClicked:(id)sender {
   113     NSTableView * table = (NSTableView *)sender;
   114     int selectedRow = [table selectedRow];
   115     
   116     [self closeConnection];
   117     [self stopResolving];
   118     
   119     if (-1 != selectedRow) {
   120         [self startResolving: [_serviceList objectAtIndex:selectedRow]];
   121     }
   122 }
   123 
   124 /* Send a BLIP request containing the string in the textfield */
   125 - (IBAction)sendText:(id)sender 
   126 {
   127     BLIPRequest *r = [_connection requestWithBody: nil];
   128     r.bodyString = [sender stringValue];
   129     BLIPResponse *response = [r send];
   130     response.onComplete = $target(self,gotResponse:);
   131 }
   132 
   133 /* Receive the response to the BLIP request, and put its contents into the response field */
   134 - (void) gotResponse: (BLIPResponse*)response
   135 {
   136     [responseField setObjectValue: response.bodyString];
   137 }    
   138 
   139 
   140 @end
   141 
   142 int main(int argc, char *argv[])
   143 {
   144     return NSApplicationMain(argc,  (const char **) argv);
   145 }