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