Re: Distributed Objects pitfalls and strategies
Re: Distributed Objects pitfalls and strategies
- Subject: Re: Distributed Objects pitfalls and strategies
- From: Aurélien Hugelé <email@hidden>
- Date: Wed, 31 Mar 2004 09:16:42 +0200
Le 31 mars 04, ` 01:15, Wade Tregaskis a icrit :
So what is the right way to do this?
the huge lack of support from Apple on this problem is very
frustrating... except the very little piece of code given by Chris
Kane
on how to make DO, there is absolutly no other piece of code showing
how to design a *both way* (ala peer to peer) communication between DO
servers and clients... i have found most answer to my question by
asking on this list, they were written by NextStep old users ;)
i noticed that *nobody* has a clear comprehension of how do DO are
actually implemented...
I sort of do. I reverse engineered the whole thing last year.
Although now I've forgotten most of it. :)
If you throw a question at me, I should be able to give you answer,
given a little time. You can also check out the source code for my
own variation of NSSocketPort, available from
<http://www.sourceforge.net/projects/securedo>, although I don't know
if it's commented enough to be self-explanatory. It is why I had to
reverse engineer DO, in order to match the secret voodoo behaviour of
NSSocketPort.
i'll look at it for sure !
basically my method to implement *both way* communication using DO is
always the same :
SERVER :
1/i start a server connection and set the root object in a thread.
2/ the server publish a rendezVous service to show its presence using
the port number of the connection created just above
3/ i make the thread "run almost forever" by looping as this :
while(shouldContinueLooping && [theThreadRunLoop
runMode:NSConnectionReplyMode beforeDate:[[NSDate date]
addTimeInterval:1.0]])
like this the server thread stops only when the
"shouldContinueLooping"
pass to NO... i dont know why but the run...untildate: variant does
not
work, i MUST use the run...beforeDate: variant...
If you add the active server port to the current runloop, you should
be able to just call "run" on your runloop, and forget about it. To
close your server down, just close down everything on that runloop
(i.e. the server and anything it creates) so that "run" exits. This
is sometimes easier said than done, in a complex app, but ultimately
it's probably poor design and/or management if you can't - so it's
good to write your app so you can. :)
i tried to call simply "run", and that works of course, except that
when i close the connection, the runloop does not exit ! using NSLog()
i saw that there were many other "input sources" added to the
runLoop... (maybe as you said poor design/management but i did not
added anything myself like timer etc...). Even chris kane (the only
person at apple that explained and give a piece of code about DO) often
says on this list that you can't really control the input sources added
to the current runloop (it depends on the frameworks you use etc...) so
he advices to poll in a while loop !
Polling once a second is, as always, an undesirable option.
basically, the "run" method is based on "runUntilDate: / runBeforeDate:
" variant and ACTUALLY poll the run loop ;)
i choosed to poll every one second, but the 1 second was a total guess,
i don't know if i should poll less often or more often...
CLIENT INSTANCE :
1/ establish a connection with the server using passed infos above
2/ ask the server to register us ! (passing the server the client IP
Address and the client port)
SERVER AGAIN :
1/ check the CLIENT INSTANCE is not already registered etc...
2/ start a connection to the CLIENT INSTANCE to get its rootProxy (you
should use enableMultipleThreads method here, but not the
runInNewThread ! (it consumes 100% of the CPU !???))
You need not do this, connecting back to the client. Why not just
have your client pass in it's representative object to the server's
register method? Save that whole slew of extra steps, and avoid
issues on the client side with port reuse.
can you explain what you call "it's representative object" (of the
client) ? if you talk about the proxy (the vended object) then i tested
it and it did not work for that reason : you can (AFAIK, quickly
tested) have only *one* vended object per connection !
so if the client use the *same* connection (created by the server), the
rootProxy is already the server ! the rootProxy can't be the client...
i must recognize that, thinking about it, there is maybe no need to set
the client as the rootProxy : if the client just pass "self" to the
server back, then the server may have a *sort of* proxy of the client
(?) please confirm this :)
What is nice with this peer to peer communication is that when a
client
quits, it can warn the server to unregister it (=> the server won't
hang or timeout when trying to talk with dead clients) and the clients
are warned too when the server die...
using the little bad tricks i explained at the beginning of this mail,
i succeeded to minimize the timeout exception and hanging problem to
the *very* little...
Just a note, I implemented this functionality in my aforementioned
NSSecureSocketPort, so that a clean close results in the other side
being notified immediately. I also implemented pinging and latency
measurements, and all those sort of bells and whistles.
this seems really powerful, since it is a complex problem, i'll
definitively look at your code !
I can't actually remember whether my port allows you to use it without
the security stuff, but if so it might be helpful to other's having
these sort of problems. If not, someone can probably hack it up so it
does.
what do you mean by security stuff ? you manage authentication over DO
? or crypt the transferred datas ??
Wade Tregaskis
-- Sed quis custodiet ipsos custodes?
_______________________________________________
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.