Also, I still recommend using AsyncSocket instead of NSStream APIs as AsyncSocket will make your life much simpler at pretty much no cost.
-Steven On Wed, Jan 20, 2010 at 11:39 AM, Carter R. Harrison <carterharri...@mac.com > wrote: > 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/steven.degutis%40gmail.com > > This email sent to steven.degu...@gmail.com > -- Steven Degutis http://www.thoughtfultree.com/ http://www.degutis.org/ _______________________________________________ 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