Re: Frustration trying to get NSConnection/NSPort working (feels like it should be simpler ...)
Re: Frustration trying to get NSConnection/NSPort working (feels like it should be simpler ...)
- Subject: Re: Frustration trying to get NSConnection/NSPort working (feels like it should be simpler ...)
- From: "Scotty's Lists" <email@hidden>
- Date: Wed, 28 Feb 2007 01:41:19 -0500
On Feb 16, 2007, at 1:21 AM, Neil Clayton wrote:
Regarding the NSConnection issues I've been having.
I've just referenced most of my "client" code from my
"trivial" (and working) xcode project.
This seems to connect find and talk to the server fine, which leads
me to believe that there is something funny with my existing (not
working) client code.
Neil,
I'll preface my comments with this disclaimer that my DO experience
is approximately 12 hours old. In that 12 hours, I've run into most
of the same non-working things that you're seeing.
I can second the recommendation of Stephan Cleaves re: the Dalrymple
& Hillegass book. The chapter on DO is illuminating and the example
works, making it a good starting point for more mad complicated DO
designs.
That said...
- (oneway void) startProcessing:(ExportParameters*)parameters
You're not specifying explicitly how DO should treat the
(ExportParameters*)parameters parameter when sending over the wire.
By default, DO would treat the parameter as "inout": meaning that DO
expects to be sending and returning the value of "parameters" between
client and server.
If the server is only going to be reading the "parameters" object
value, you should probably make that explicit by changing the method
signature to...
- (oneway void) startProcessing:(in ExportParameters*)parameters
This is supposed to reduce network traffic (DO is informed that the
parameter doesn't have to be sent back to the client from the
server). Maybe it's just a performance thing, but it seems that
anything you can do to keep port (network) I/O down is a step toward
a less mysterious DO application.
You also don't specify whether DO should treat the parameter as
"bycopy" or "byref". DO can either serialize the "parameters" object
and send those bytes over to the server for reconstitution in the
server's address space ("bycopy") or DO can set up a proxy object for
"parameters" on the server side and do port I/O to get (and return)
its value from the client ("byref").
I don't know how DO treats the parameter when you don't specify
"bycopy" or "byref" in the @protocol method signature (I'm lacking DO-
fu on this point).
- (oneway void) startProcessing:(in byref ExportParameters*)parameters
With this signature, DO knows that the server will be referencing the
value of the "parameters" object from the client's address space
through the black magic of DO port I/O. A "byref" parameter implies
port I/O whenever the server needs to access its value. When you
message the "parameters" object, DO will send the message to the
server-side proxy, which bounces it over the port to the actual
client-side object, where the message is evaluated, the value
marshalled and sent back over the port to the server-size proxy,
which returns it finally to your caller. Seems like opportunities
for the server process to block waiting for port I/O to complete.
- (oneway void) startProcessing:(in bycopy ExportParameters*)parameters
With this signature, DO knows that it should send an actual copy of
the "parameters" object over to the server. When the server messages
the received "parameters" object, it will be doing so on a local
server-address space copy, not over the port.
A gotcha that I just learned today is that DO doesn't support keyed
archiving (i.e. NSPortCoder, which does the magic of serializing an
object for transport over a port, only supports classic archiving,
not keyed archiving). If you're using "bycopy" on an object of your
own design, you have to implement the NSCoding methods in your class
and you can't use keyed archiving, or DO bycopy parameter passing
will not work.
<http://www.cocoadev.com/index.pl?
TransferringACustomClassOverNSConnection>
<http://www.cocoabuilder.com/archive/message/cocoa/2007/2/21/179157>
Also, if using bycopy, the server application has to have the class
of your object loaded in its runtime environment (ie. it has to be
able to create instances of your class). In your case, the .m/.h
files for the ExportParameters class need to be compiled into the
server app.
And there's a lot of interaction between DO, threads and runloops.
For instance, the docs mention that [NSConnection defaultConnection],
while returning a perfectly good NSConnection instance, might not
actually be available for your own use.
<http://developer.apple.com/documentation/Cocoa/Conceptual/
DistrObjects/Tasks/vending.html>
Although every thread has an NSConnection instance available (this is
what the defaultConnection method returns), that connection instance
could already be being used for some other purpose. Your best bet is
to create an explicit NSConnection instance for your own app's use.
Using the "Chatter" example from the Dalrymple & Hillegass "Advanced
Mac OS X Programming" book (which, BTW, does kick some mighty ass), I
was able to get the simple but illustrative DO client/server apps
running with vanilla NSSocketPorts. Later, I was able to swap in
NSPorts and still keep it working. I couldn't get NSMessagePorts to
work in it, though, nor could I get NSSocketPorts to work with a
socket that I created and configured using BSD API (socket,
setsockopt, bind, listen). It wasn't readily apparent what was
going wrong, but the resulting stack traces ended really deep in
Foundation framework code...generally a clue that I didn't set
something up correctly.
My DO-fu is only a few hours deep. I bet if I can boost my
mitochlorian count up a little higher, DO will unfold before me like
a Rand McNally atlas. Or not.
Scotty
_______________________________________________
Cocoa-dev mailing list (email@hidden)
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:
This email sent to email@hidden