I need some folks experienced with cocoa and socket programming to weigh in for 
me on some design problems I've been having.  I'm designing an application that 
acts as a client in a client-server model.  The client communicates with the 
server over the network by issuing a request and then receiving a response.  
Requests can only be issued one at a time, meaning that a request cannot be 
sent until a response from any outstanding request is first received.  My 
application works in such a way that the it could request a handle to an object 
on the server and then use that handle in subsequent requests to retrieve 
additional information about the object.  I see two ways of modeling the 
application - I've tried both and I'm not particularly happy with either.

The first is to send a request, and then have the socket block until a response 
is received.  This benefit to this model is that it is so much easier to write 
the higher level application code.  The issue with this model is that over a 
slow network connection it can take a considerable amount of time for the 
response to come back from the server and while that is happening my CPU usage 
is through the roof b/c the thread is blocking.

The second way is to send a request and then let the NSInputStream call a 
delegate method when the response data is available.  The response data is then 
pushed up through my protocol stack and finally up to the higher level 
application code.  The benefit to this method is that CPU usage is minimal due 
to the fact that I'm no longer blocking, but the downside is that the higher 
level application code is so much more difficult to write because I have to 
write about a thousand methods to act as a callback for each request in a 
series of requests.

I've provided an example of how I see each working below.  My first question 
is, is there other ways to design an application around this client-server 
model that I'm not thinking about?  My 2nd question is, if there aren't other 
ways, how can I adapt either method that I have outlined to make it work a 
little bit better?

As an example let's say the server knows about the following objects:

1. VendingMachine
        - An object that represents a vending machine.
        - A vending machine contains Soft Drink objects.
2. SoftDrink
        - Has the following properties: drink name, price, number of calories.

If I use the blocking model, I could write my code like this.  The code is 
simple to write but I'm forced to wait for the server to respond with 
information on pretty much every line of code.  If the vending machine had 
enough soft drinks it could take a long time to iterate over each one and have 
the server respond with the drink's name of each drink.

-(void)printDrinkNames
{
        VendingMachine *machine = [server fetchVendingMachine];
        NSArray *softDrinks = [machine getSoftDrinks];
        for (int i = 0 ; i < softDrinks.count ; i++)
        {
                NSString *drinkName = [[softDrinks objectAtIndex:i] name];
                NSLog(@"Found a drink named %@", drinkName);
        }
}

Likewise if I do the non-blocking approach I would have to have a method that 
gets called for each step in the process (see below).  This model drives me 
crazy b/c the higher level application code is long, has tons of methods, and 
is just difficult to read and maintain.  The example I have provided is simple 
enough to get the point across, but in reality some of the processes I'm trying 
to drive are much more complex and require numerous callback methods to pull 
off.

-(void)printDrinkNames
{
        [server fetchVendingMachineWithCallBackObject:self 
selector:@selector(didFetchVendingMachine:)
}

-(void)didFetchVendingMachine:(VendingMachine *)machine
{
        [machine fetchSoftDrinksWithCallBackObject:self 
selector:@selector(didFetchSoftDrinks:)];
}

-(void)didFetchSoftDrinks:(NSArray *)drinks
{
        for (int i = 0 ; i < drinks.count ; i++)
        {
                SoftDrink *drink = [drinks objectAtIndex:i];
                [drink fetchNameWithCallBackObject:self 
selector:@selector(didFetchDrinkName:)]
        }
}

-(void)didFetchDrinkName:(NSString *)name
{
        NSLog(@"Drink name is %@", name);
}

_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to