the Zell solution ... it works!
the Zell solution ... it works!
- Subject: the Zell solution ... it works!
- From: JP May <email@hidden>
- Date: Sun, 08 May 2011 20:37:25 +0200
Hi Lou,
> "What I can tell you now, though, is if you stop the NSNetServiceBrowser you should see much better performance when bluetooth is on
Lou - you're a genius !
Did I mention -- you're a genius.
What can I say but thanks.
One thing disturbs me: we did a boatload of testing the last 36 hrs, and, as far as I can see:
(*) the Zell solution is a TOTAL solution.
I am slightly disturbed, because I think in your messages you mentioned, for you it is a "pretty good" solution.
We made apps with charts, averages, green lights and so on, and on a Problem device (ie: bluetooth running), Zell Solution turned on, by the numbers it is perfect. I did not once see any sort of crappy performance, using the Zell solution.
Maybe once or twice, I had a emotional feeling it was working a bit jumpy -- but it flies planes great and all the telemetry I could shove in the server appeared to show "perfect" you know.
So to repeat, I'm disturbed that for you, it is more of a partial solution? Or maybe I got the wrong sense.
To be clear:
1) we apply the Zell Solution to the CLIENT only. (Perhaps it's even better if you do something similar on the server, I don't know.)
2) if it matters, we were/are using CFNetServices rather than NSNetServces.
3) as soon as bonjour resolves (i.e., I have a hostname string and port number), I shut down the service browser. Once it is shut down, only after that I then launch the actual client (indeed, CocoaAsyncSocket, latest version, specifically --- WITH anti-Nagling, FWIW -- that happens in didConnectToHost: which you can see below).
4) FTR I generally test at 40hz, which is just a sort of consensus value, and works great for mouse-like networking, i think, and is not too crowded if you have a few clients connected.
5) I had a large # of devices to test with, and 2 different hubs.
When I do all that it works flawlessly, even if the device is a problem device (bluetooth on) .... thank you Lou Zell, GENIUS !!!
Another point: You mentioned:
> If you only need to find devices when you first launch your app, then this could be enough. Unfortunately, if you have an app where other devices can join later, you'll have to get creative :)
Just to be clear, I apply the Zell Solution on the CLIENT. (I'm gonna test it on the server as well.) Your sentence there sounds more like you are referring to a server than the client side. I just mention this in case there is some confusion or mixup.
Thanks !
Fat Johnnie
// documented code...
-(void)_find
{
NSLog(@"I am launching bonjourServiceBrowser with the _resolveIt callback.");
CFNetServiceClientContext clientContext = { 0, self, NULL, NULL, NULL };
// it's a CFNetServiceBrowserRef ...
bonjourServiceBrowser = CFNetServiceBrowserCreate(kCFAllocatorDefault, _resolveIt, &clientContext);
CFNetServiceBrowserScheduleWithRunLoop(bonjourServiceBrowser, CFRunLoopGetCurrent(), kCFRunLoopCommonModes);
if ( CFNetServiceBrowserSearchForServices(bonjourServiceBrowser, CFSTR(""), CFSTR("_teste._tcp"), NULL) == false )
{
CFNetServiceBrowserUnscheduleFromRunLoop(
bonjourServiceBrowser, CFRunLoopGetCurrent(), kCFRunLoopCommonModes);
CFRelease(bonjourServiceBrowser);
bonjourServiceBrowser = NULL;
NSLog(@"searching for services went to hell ..");exit(0);
}
/*
Later .. "To shut down a CFNetServiceBrowser that is running in asynchronous mode,
call CFNetServiceBrowserUnscheduleFromRunLoop,
then CFNetServiceBrowserInvalidate,
then CFNetServiceBrowserStopSearch."
*/
}
void _resolveIt(CFNetServiceBrowserRef browser, CFOptionFlags flags, CFTypeRef domainOrService, CFStreamError* error, void* info)
{
NSLog(@"This is the browser callback function.");
NSLog(@"Note that error is: %@", (error == nil)?@"nil":@"NOT nil");
BeAClient *wtf = (BeAClient *)info;
// if you are confused by that line of code, it just helps this object "find itself" below at _launch:atport:
NSLog(@"I am launching the resolver...");
if ( flags != kCFNetServiceFlagIsDomain ) // since 'not a domain', it's a CFNetService
{
if ( ! CFNetServiceResolveWithTimeout( (CFNetServiceRef)domainOrService, 10, NULL) )
{ NSLog(@"could not resolve!"); return; }
[wtf _launch: [NSString stringWithFormat:@"%@", CFNetServiceGetTargetHost((CFNetServiceRef)domainOrService) ]
atPort: CFNetServiceGetPortNumber((CFNetServiceRef)domainOrService) ];
return;
}
// domainOrService result was the unappealing 'domain' type (whatever the heck that is ..)
NSLog(@"stuck in odd place...\n\n");
}
-(void) _launch:(NSString *)lahostname atPort:(int)laport
{
NSLog(@"resolved, launching my client... %@ %d", lahostname, laport);
// be sure to apply THE ZELL SOLUTION at this moment.
// If you do not do this, networking will not work if Bluetooth is incidentally running on the client device.
// courtesy LOU ZELL, GENIUS
//
NSLog(@"but first, I will shut-down the browser..");
[self _shutDownTheServiceBrowser]; // Zell Solution
NSLog(@"Returned from shutting-down the service browser. I will now launch the actual client.");
self.client11 = [[AsyncSocket alloc] initWithDelegate:self];
BOOL rez =
[self.client11 connectToHost:lahostname onPort:laport error:nil];
NSLog(@"Launching client, rezult is: %@", rez?@"Y":@"N");
// run at 40hz from the client......
[NSTimer scheduledTimerWithTimeInterval:0.025
target:self selector:@selector(_tick) userInfo:nil repeats:YES];
// possibly flip the run loop here if that could possibly matter, if you're doing something large on the UI perhaps
}
-(void)_shutDownTheServiceBrowser // courtesy LOU ZELL, GENIUS
{
NSLog(@"Client: I am shutting-down the service browser.");
CFNetServiceBrowserUnscheduleFromRunLoop(bonjourServiceBrowser, CFRunLoopGetCurrent(), kCFRunLoopCommonModes);
CFNetServiceBrowserInvalidate(bonjourServiceBrowser);
CFNetServiceBrowserStopSearch(bonjourServiceBrowser, nil);
// "CFNetServiceBrowserStopSearch -- calling this function causes the callback function associated with the CFNetServiceBrowser
// to be called once for each service found - error is passed to the callback function."
NSLog(@"According to the doco, CFNetServiceBrowserStopSearch just called should now call the _resolveIt callback function:");
// (interestingly FTR, testing shows that does not happen with recent OS. watch out for it)
//
// and finally, do we release it memory-wise?
/* "Core Foundation functions have names that indicate when you own a returned object:
Object-creation functions that have “Create” or "Copy" embedded in the name:
If you own an object, it is your responsibility to relinquish ownership (using CFRelease) when you have finished */
CFRelease(bonjourServiceBrowser);
NSLog(@"I shut-down, invald, stopped and released!");
}
//////////// the following example shows how to disable Nagling ... similar on client or server side ...
#import <arpa/inet.h> // needed only for IPPROTO_TCP
#include <netinet/tcp.h> // needed only for TCP_NODELAY
- (void)onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port
{
NSLog(@"client - didConnectToHost");
// Direct from R. Hanson, "try disabling Nagle..."
CFSocketRef cfsock = [sock getCFSocket];
CFSocketNativeHandle rawsock = CFSocketGetNative(cfsock);
int flag = 1;
int result = setsockopt(rawsock, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(int));
if (result != 0)
NSLog(@"Could Not Disable Nagle...");
else
NSLog(@"Nagle Is Disabled.");
}
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Macnetworkprog mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden