• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Distributed Objects pitfalls and strategies (SOLUTION (?))
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Distributed Objects pitfalls and strategies (SOLUTION (?))


  • Subject: Re: Distributed Objects pitfalls and strategies (SOLUTION (?))
  • From: John Scalo <email@hidden>
  • Date: Tue, 30 Mar 2004 17:31:39 -0800

Thanks to everyone who took some time contribute to the discussion, especially Wade. And sorry if my responses tended to be of the "I already tried that!" nature. I really did try lots and lots of variations on the theme.

I'm hesitant to say I've found the solution, but early testing is looking really good! So here goes...

If you want to create a distributed objects solution which runs across a network, uses a fixed port #, deals with multiple user logins, Panther fast user switches, can vend to multiple clients, and clients can see multiple servers, here's what seems to work. (This omits rendezvous discovery, which I'm using but seems straightforward and trouble-free.)

=== The Server ===

* Be sure to observe NSWorkspaceSessionDidResignActiveNotification notifications and close your connection when the user of your process is no longer active. This is related to Panther fast user switching, and two instances of your server are not going to run correctly on the same computer if they're serving over the same port.

Then (no error checking for brevity):

int newSocket = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in serverAddress;
int namelen = sizeof(serverAddress);
memset(&serverAddress, 0, sizeof(serverAddress));
serverAddress.sin_family = AF_INET;
serverAddress.sin_addr.s_addr = htonl(INADDR_ANY);
serverAddress.sin_port = MY_PORT_NUMBER;
int one = 1;
setsockopt(newSocket, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
bind(newSocket, (struct sockaddr *)&serverAddress, namelen);
listen(newSocket, 128);

NSSocketPort *newPort = [[NSSocketPort alloc] initWithProtocolFamily:PF_INET socketType:SOCK_STREAM protocol:0 socket:newSocket];
NSConnection *theConnection = [[NSConnection alloc] initWithReceivePort:newPort sendPort:newPort];

The key here is to set the SO_REUSEADDR and *not* the SO_REUSEPORT option. This is what was killing me before. I found other references suggesting SO_REUSEPORT, but apparently they are wrong. I tried SO_REUSEADDR on a whim. If you don't do this, then if your server gets quit and relaunched while there is an active connection, it will take 10 minutes before it can create a new port. Yes, it really is 10 minutes and not 2. I don't know what kernel constant this is tied to, but it's consistently 10 minutes.

=== The Client ===

Nothing unusual here:
NSString * ipAddressString = NULL; //find this using rendezvous or whatever
NSSocketPort *connectionPort = [[NSSocketPort alloc] initRemoteWithTCPPort:MY_PORT_NUMBER host:ipAddressString];
NSConnection *connection = [[NSConnection alloc] initWithReceivePort:NULL sendPort:connectionPort];

Happy object distributing!
~ John

Is there any reliable and resilient way to set up a DO server/client? By reliable and resilient, I mean something that can withstand server stops and starts, multiple user logout/logins, Panther fast user switching, and deals with multiple clients and servers running on the same network. It's not hard to get something that works most of the time, but that's not good enough in this case. I've tried a few different strategies, but each has its problems. From an earlier discussion, the solution seemed to be to set up the BSD socket manually and set the option to allow port reuse. But that introduces more issues. Here are the things I've tried-

-- Neither client or server is set to reuse ports -- (aka Plain Ol' Distributed Objects)
i.e. the server does this:
NSSocketPort *newPort = [[NSSocketPort alloc] initWithTCPPort:MYPORT];
NSConnection *connection = [[NSConnection alloc] initWithReceivePort:newPort sendPort:newPort];

and the client does this:
NSSocketPort *connectionPort = [[NSSocketPort alloc] initRemoteWithTCPPort:MYPORT host:ipAddressString];
NSConnection *connection = [[NSConnection alloc] initWithReceivePort:NULL sendPort:connectionPort];

Problems:
* Client hangs when server disappears and then generates timeout exceptions.
* Server can't make new NSSocketPorts after successive user logout/logins for about 10 minutes.

-- Server set to reuse ports --
i.e. the server uses initWithProtocolFamily and the client uses initRemoteWithProtocolFamily, setting up their own BSD socket bind()ing, and listen()ing. Each calls setsockopt(newSocket, SOL_SOCKET, SO_REUSEPORT, &one, sizeof(one)) before binding.

Problems:
* Client hangs and gets timeout exceptions trying to resolve connections after the server process has been stopped and started again. e.g., a user logs out and another logs in.

-- Both set to reuse ports --
Problems:
* If there are multiple servers running on the network, then messages sent to a connection's proxy go to a random server, not necessarily the one the NSSocketPort was created for.

-- Use dynamic private ports --
Since port #s are unique, there isn't an issue of making new connections, but this isn't workable if the user has a firewall, or outside the local network.

So what is the right way to do this?

Thanks
~ John
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.


  • Follow-Ups:
    • Re: Distributed Objects pitfalls and strategies (SOLUTION (?))
      • From: mmalcolm crawford <email@hidden>
    • Re: Distributed Objects pitfalls and strategies (SOLUTION (?))
      • From: Aurélien Hugelé <email@hidden>
    • Help with Memory leak
      • From: Vince Ackerman <email@hidden>
References: 
 >Distributed Objects pitfalls and strategies (From: John Scalo <email@hidden>)
 >Re: Distributed Objects pitfalls and strategies (From: Aurélien Hugelé <email@hidden>)

  • Prev by Date: Re: FTP & SFTP?
  • Next by Date: Synchronizing GUI-code necessary?
  • Previous by thread: Re: Distributed Objects pitfalls and strategies
  • Next by thread: Help with Memory leak
  • Index(es):
    • Date
    • Thread