WWDC2003 Session 106

Transcript

Kind: captions
Language: en
what I'm here to talk about today is
application inter application
communication on Mac OS 10 there are a
lot of different ways of achieving in
your application communication but I
want you to get out of this talk the
understanding of what frameworks are
available and some of the different
limitations of the frameworks so when we
talk about indoor applications
communication when you get right down to
it the operating system is kind of like
just another application when you
request a service from the operating
system you're you're making an inter
process call and the the colonel is
going to give you back some result and
it really lets you think about the whole
system as individual applications are
building blocks just like framework for
building blocks that let you build your
application only when applications are
participating in inter process
communication they can all be put
together by users that's really
scripting and I'll get to scripting
quite a bit later so there are different
frameworks in our systems our system has
a long legacy from unix to mac OS 9 api
is 70 guys an objective c api and it
keeps growing into the future and all
these different api's are going to be
available to us so this is what i'm
hoping you'll learn coming out of the
session what frameworks are available
what api's are available at familiarity
with these AP is and what they're all
capable of I want you to be able to
decide whether there's an existing
conversation someplace that it would
make sense for you to participate in the
scripting conversations there's a
well-established community of scripting
that's available so you would want to
plug into that with your application so
that scripters can script your
application and then there's finding
someone to talk to this is actually a
really important thing and because of
the way our system partitions
applications into their own address
space the behavior of finding somebody
to talk to is different in mac OS
Cameron it's ever been in Mac OS 9 this
has been there's been a lot of confusion
about this and how things don't quite
work the way they did under mac OS 9
and I'm hoping that we'll be able to
explain some of why that is so here the
frameworks that we're basically going to
talk about is the unix and mock api that
came out of while darwin basically and
apple events that objective c
distributed objects the reports of
application layer api it's a much higher
level of doing an across
miscommunication these can both be used
locally between processes and over the
network with other applications running
running on other machines and then
finally web services and what we're
doing with web services in the
application frameworks all right so
here's our bubbly diagram shows
basically we're POSIX and eunuch live
and mock messaging leads right at the
bottom application frameworks was on top
and then your application flows on top
of that so let's talk just first about
positive screams oz extremes are well
POSIX pipes and sockets it typically
screen-based what we mean by that is
you're going to write a bite in one end
and you're going to read a bite out of
the other and there are a couple of
different AP is in that space pipe and
socket are probably the most common this
is how you create one of these file
descriptors that you're going to write
data to or read data out of the the two
and parentheses overlay that means
there's a man page for this I know a lot
of you are old Mac developers some of
your unix developers ma'am gauges are
going to be somewhat new to mac
developers that haven't used unix a lot
so when you see that too go ahead and
take Man two pipe and you'll get some
information about it so pipe and socket
are ways of creating a file descriptor
socket can be used to create
inter-process file descriptors that's
the AF unix address family and it can
also be used to create tcp/ip pipes so
that logically you're just writing to a
file descriptor but you're really going
out over a network and talking to
another site now the important thing
about file descriptors is that by
default they're going to block if you do
a read and there's no data available
your process is now blocked waiting for
that weed to complete
so if you have multiple file descriptors
that you want to read from you don't
want to do that you don't want to have
three threads or blocked and read you
want to use a function called Celeste
this lets you say here are a bunch of
file descriptors that I want to know one
day that becomes available or when their
state changes so let's take that array
and it blocks and then return when there
is data available and the last thing is
shared memory on our system shared
memory well I'll talk about in more in a
few slides but basically it's a way of
presenting data to other applications
and typically you don't want that data
to be changing wall of their
applications for using it i'll talk
about that in a couple slides all right
so pipes and sockets are the most
portable inter-process communication
mechanism on our platform as long as
most portable means other UNIX is if
you're coming from if you're putting a
lining application chances are is its
using pipes and sockets it's just going
to work out of the box and that's fine
there's nothing wrong with that but it
isn't well supported by the mac OS an
application framework because your
application especially applications with
you lie are receiving events for
multiple sources events are coming in
from the windows server events are
coming in from i/o kit you need to be
able to capture all these events in a
single place so that's what the run was
this for so if you're trying to read
data out of a file descriptor you're
going to want to wrap it in something
that has some affinity for the run loop
it's going to allow the run loop to do
its job of be multiplexing several
incoming messages and sending them to
your application letting your
application deal with it CF scream part
of the core foundation network does this
by sort of emulating select the it's an
implementation detail how that works but
the upshot is you can use a CF stream
wrapped around a file descriptor and
receive notifications when data is
available and that's a really good idea
if you're trying to do file descriptor
base i/o within a higher level
application so pipes and pockets aren't
terribly
mission for large transfers of data
arbitrary data because every bite that
gets written its read out the other side
what you see then is just a linear time
to send a message depending on the
message size so the best use for provide
some sockets that you're going to see is
reading output from a fork command when
you call forth in your application the
child process of haratz your file
descriptors so the child classes
commence start reading and you can just
write byte and the child process reads
and communicates back and forth that way
that's typically how you're going to see
a pipe and particular use there's also
named pipes which allow you to create a
node in the file system for other
applications to connect to to write data
to so shared memory is you know can be a
great way of sharing them or a between
applications but the problem here is
that typically you're going to have one
person performing updates let memory and
other people reading it when one of the
other people reads from that memory the
most it can be guaranteed a TREB
atomically is 32 bits so if application
a has perform some operation and built a
certificate or something that I want to
share among applications it has to
somehow flags that to another
application that all that memory can be
read and that the other application was
able to read all that memory without a
changing underneath that's why I say it
requires some sort of external
synchronization that could either be a
checksum on the memory that was read or
perhaps using a file descriptor just
sitting all okay the data is available
tell me when you're done reading it then
I can unlock this memory and keep going
so the best use for shared memory then
is going to be to share work that you've
done among several other applications so
there's a new unix api in mac listing
panthers this has been the notify api
and what it allows you to do is to
subscribe for notifications that
something happened now what that
something is is entirely up to the the
notification that's being defined
the notification has no payload
associated with it it's just an
indication that something happened
because of this or regardless of it you
know the notifications can be coalesced
if 10 things happen you may only hear
about one of them because all these
notifications will be coalesced into one
event delivered to your application your
applications subscribe to notifications
it can either poll for them or it can
listen on a file descriptor or receive
them via mock message and one way to
think about this it's a better signal
signal is traditionally how you tell a
UNIX process well go away you're dead
now or reread your preferences file that
would be fig hot a lot of times problem
with signal is you have no control over
when your process is going to receive a
signal so when people in the past if you
signal they might want to say oh well
you know I got my signal I'm going to
use some application API you can't
really do that it's like interrupt time
in mac OS 9 you don't know the state of
all the framework so notify would be a
better way to architect your processes
so that you have some control over where
events come in the specific one off
notifications so here's a code sample
it's a student evil this is how the
client is going to register to receive
notifications there's a new call notify
register file descriptor and you give it
the name of the notification want to
subscribe to in this case it's handing
back of file descriptors that I'm going
to block in read I already said you
don't want to do that this is a sample
it also hands back a token that
represents that notification so that we
can delete it later then I'm just going
to read from this and my read is going
to block until the notification actually
is sent by another process notifications
how do we want to say this later on
we're going to see that there are
different partition spaces for
applications to run in notifications are
global across all of them so the server
which is typically running in another
process just says notified post anybody
who subscribe
notification using any of you know file
descriptor mach port delivery or ya
think even signal it will even positive
signal anybody to subscribe to that
particular notification will then
receive it so you get all your
applications going boom boom boom boom
updating some information perhaps
rereading a preference file ok so back
back to the architecture diagram the
next thing I want to talk about is mock
messaging itself and it would be the
subject of a much longer talk discuss
everything about mass messaging so what
I'd like to have happen is for us to
understand some of the terms that we use
when we talk about Mach messaging and so
that when you run into it you're not
startled or you're able to work with
code that uses clock messaging so the
first thing is that Monta messaging
allows you to implement servers servers
exist all over the system the windows
server is even that server in the name
is responsible for handling user events
and sending them to your application in
effect your application is a server
because it receives events and perform
some action based on them so servers
exist in your process and other
processes and in the tunnel the kernel
provides some servers for doing things
like us now getting the time of day for
example to be a server when you send a
mock message these are some of the terms
that you need to know need to understand
what it is that you're sending into the
kernel mock message itself is the name
of the colonel trap this is the the
subroutine looks like to an application
developer that you call to send a
message and and actually to receiver
replies same travel mock message header
key is the name of a structure that
contains the actual mock message data
it's a variable-length structure it's
got a header that sort of defines the
size of the structure and then they're
going to be in the variable length part
there's what are called descriptors
for out-of-band memory regions and mop
courts so MOT sport you're going to see
these all over the place and when you
get down to it it seems like everything
is a mod for tasks seem to be a mask for
threads seem to be in lockport so when
you stand on our message you send it to
a mach port porch have rights associated
with them you can have a receive right
on a port that means you're allowed to
receive data somebody else has a send
right on that port that person can send
data you can receive it there's also a
send once right and this is used when
you send somebody an event and you want
to reply back you can send them a send
once right on a court they're allowed to
send you exactly one message back on
that port you receive it in the deal
with the reply this is a kind of a
security thing you don't want people
just sort of blasting messages out to
port that they don't have rights to do
so on there's also something called a
court set which is itself that looks
like a port a port set is effectively
the same as a select call it actually is
an FD set which is the parameters to a
select call you can select multiple
ports into a pork set and then with one
mocks message call monitor all those
ports for an event to come in what's
interesting about that is the run loop
in CF unloads does that for you so if
you use the core foundation wrappers on
top of mount ports you'll get the
behavior of an entire selection of
courts being received upon it at once
and that's that's a really good thing
because you don't have to have 10 people
block and mount message out of their
memory is a really important concept and
it is basically lets you send a message
to somebody else sharing your memory but
when the receiver gets the memory he
doesn't strictly own it he's allowed to
read from it if you give him that option
and he's allowed to touch it but if he
touches it he's going to get a copy of
the memory now a lot of some sub systems
are built on top of this because
typically when you mess
data to someone they're going to read
from the data but they're not
necessarily going to write to it so that
a band memory descriptor it provides
virtual copies of memory between
applications you're given the option of
marking it read only your copy on write
when it gets a message to the other side
one thing to note is that the memory
that you send should be page aligned the
reason for this is that if you message
memory that's not paged aligned then the
colonel is going to copy the first and
last page make new pages for those and
zero out the stuff that isn't actually
explicitly sent so ideally you're going
to send multiple pages of paged online
data that's not always possible and
sometimes you'll wind up with pages copy
things besides this is a process called
boxcar you don't want you know if the
block before hand is a pointer that's
kept you know the users password you
don't want that going to another
application so by aligning the memory
you'll get much better performance
through my message you need to plan for
memory management when you receive a
mock message that has out-of-band memory
in it you need to deallocate that memory
you you own that memory or you own you
know you think that you own it but the
colonel will take care of copying it is
necessary but you need to deallocate it
otherwise it will just leave and consume
you know vast resources so vmd allocated
to call you use to do that whatever the
address is that came in to you Museum
deallocate to deallocate it later you
don't have to do that right away you can
hang on to that memory for as long as
you want just be aware that you own it
and you still need to get rid of it okay
so a mock message structure is going to
be an example mock message basically
it's a green box with the very top
there's a mass message header T this is
where you specify the message ID this is
how the receiver of the message is going
to be multiplexer messages and decide
what to do with it the size of the whole
green box and the reply port the port
that is going to get sent back
from the mock from the server that
responds to this then this is all
variable length data after it and but
the first thing after verte after the
header has got to be the descriptor
count which could be 0 the descriptor
count in this case is going to be too
we're going to have to descriptors
following the mock message header key
the first descriptor we're going to send
an out of line memory region this is a
gem these descriptors are fixed length
structures you fill in attributes of
them and just append them to the end of
the message so from out for an a-line
memory region it's just the address and
the size and while it would be nice if
the address where page aligned if it's
not the modulus of trap will take care
of that for you there's also the
attributes and in that memory descriptor
about how to deal with the memory
whether or not the memory should be copy
on write or read only in the server
process then in this example I'm also
going to send a mach port this might be
the case where I'm telling the server
here's some data process this out of
line data and when you're done doing
that work you can contact me on this
mosport that the work is complete after
that you can have whatever data you want
so what you're going to see a lot of
times that a mock message typically will
have 0 descriptors and it will have a
whole bunch of just data fitting after
the header and that's really the body of
the message corefoundation in the CF
mach port de muxing routine it allocates
a certain amount of space on the staff
receives a mop message but if the
message is too big it allocates a larger
buffers and then does the work again so
ideally you want to keep your message
size small it's kind of an
implementation detail of CF not court
but it's interesting that it's a message
that you're receiving is too big for the
buffer you supplied you get a chance to
allocate a larger buffer and receive
them
again obviously that's less efficient so
you want to make sure if you're
receiving the event yourself that it is
the minimum size or so the maximum size
of all the messages that you're likely
to receive so how do you find somebody
to talk to with them with a mock
plantation this is probably one of the
most important things now because fast
user switching you have to discover mock
services and you do this through a
mechanism called the bootstrap server
this associates a symbolic name with a
server there are several bootstrap
servers on the system when the system is
starting up there's the primordial
bootstrap server this is where demons
live with what we call them startup
items in our in our new lingua when a
server that is running in a startup item
it starts up or it registers itself with
a bootstrap server it is then visible to
other bootstraps terrific it created
after the fact so if you're running
within an application context you're a
net scape plugin inside of Safari you're
allowed to see service is ended by demon
let me go on to the next slide this will
show it a little better demons live in
this this little world out here user a
applications and user be applications
are allowed to see into the demon world
demons can't see into they cannot load
up services that are vended by processes
within the users bootstrap ports that
within these boots reports that were
created for the user this is why you
cannot send an apple of em in Jaguar
from a demon or an Apache module two
items for example this is done for
security reasons we don't want just
arbitrary code running in the bootstrap
server world to be able to manipulate
user land applications so
how do you write a mockolate how do you
decide what the structure of a
mathematician is going to be you can do
it by yourselves you can roll your own
is a real pain or you can use Meg the
mock interphase generator this is an IDL
for describing the structure of the
mosque message it handles marshaling
parameters of scalar types and
descriptor types into a mock message
sending it to the server and processing
the response giving it back to you in a
way that fits in easily with with your
application it associates a unique ID
with each message and it provides a
deluxe ting routine that takes care of
switching on that ID and calling your
server implementation so here's an
example you see a lot which is a check
in on a server where this would be used
is a demon that wants to provide a
service for a user application the user
application will check in with the demon
and say I'm here I'm ready to do some
work for you here's my name that's an ID
in obviously you're saying this is an
input parameter for the server ID is
just a variable name and in this case
the the parameter is a c string the
server then is going to provide a mach
port in this case would see a mach port
that the client can then send additional
requests upon so when requests come in
on this mod port to the server he's
going to be able to say oh I know what
court that is I know what client checked
in and I handed that board out too so I
know like what state I had kept for that
application previously what gets
generated from this is client glue if
you look in user include mop you're
going to see a bunch of deaths files and
also the generated header files for
those mock services and they basically
look at it it's just see glue code the
first parameter is the server port this
was discovered via bootstrap look up or
handed back from some other routine then
just a char star ID they will take care
of putting that into the body of a mock
message
and then as an out parameter the client
port that the server is going to provide
it also generates this stub routine for
the server to implement now if someone
hands you a depth file and says call my
service you don't need the server glue
but if you're going to implement a
server you have to basically provide the
body of this routine and for the end in
the demo alg I'll show what that looks
like so how do you handle a mock message
you get the data you cast it to a mock
message header key and you switch on the
message ID but that's kind of a pain so
there are two utility routines that you
should know about mock message server
and mock message server one both of
these take the mach port that you
registered with the bootstrap server and
the d-max routine that make generated
and in the first case mock message
server will sit there in a loop
accepting messages calling your DMX
routine sending the reply mark message
server once does that but just one
sending applies is kind of difficult
because you have to figure out first
whether a reply is warranted and second
you have to deal with well the d-max
routine returned a mock message header
of an appropriate size you have to worry
about what that size was and and deal
with errors that occur in sending it
what I would recommend is if you need to
send a reply directly to go to the
Darwin sources and grab the source code
amok message server and you sort of
understand that copy and paste it into
your your stuff with appropriate license
whatever anyway corefoundation has
support from op and it has this in a
couple different ways but the most
important very CF MOT sport which wraps
around a fort optionally it creates it
for you and it gives you a call back
routine so when you register a mock TF
mach port run loop source with your run
loop and an event comes in it's going to
call your call back Akeem say hey here's
a mock message but like the previous
slide alluded to it doesn't send the
reply for you in that case you're going
to have to set up the the reply
structure yourself and send it and again
going back
to the mass message server routine to
understand how to send that reply if you
want to deal with mock messages the SCF
mach port generated by meg that's
probably the right way to do it it gives
you an invalidation mechanism this is
really important because say somebody
checked in with you and says i'm going
to i want you to do some work call me
back on this mach port and then that
application crashes or the user quits it
the invalidation mechanism lets you know
that the mach port that you're holding
right now you can't do anything with its
now invalid and if you're doing work on
behalf of that lockport you could stop
now because nobody's ever going to hear
about it CF message port sits on top of
CF Mosport and it sits on top of the
bootstrap server and it lets you create
basically a mock server that accepts a
blob of data this is a really handy
thing to do if you just need to send
data between two applications CF message
port is probably the right way to do it
it has restrictions of the bootstrap
port world though so between between
sessions it's not going to work it'll
work a demon can advertise the server
and clients inside the user application
will be able to send to it but userland
applications per user applications i
should say aren't going to be reachable
from other other user sessions or from
demon now what's up the performance of
all this this these different in lower
level AP is well pipe is basically
linear this these are the numbers that
came out of the the test app I wrote
that sundaya five Meg blob to a to a
process plate with sport mock message on
the other hand basically is completely
flat it was kind of independent of the
message size obviously the memory was
allocated all beforehand and then and
then sent along so my fetchers seem to
be you know just a great way than
message arbitrarily large blobs of data
turns out and I don't even know if
that's visible CF message is pretty much
just as efficient as doing the mach port
hand-rolled mock message directly that's
why I would really recommend it
especially if you don't need to do
intercession communication ok so let's
go up a layer talk about apple event
first let's define what we mean by apple
events it's kind of weird that the word
apple event means so many different
things it's like calling every product
net so Apple event came around in 91 I
think is the first I've heard about them
apple event is the technology and the
name of the framework it's also the name
of type in the framework and apple event
descriptor record and it's also you know
apple event which is what we're all act
today this is an apple event it's under
the application services umbrella what
that means is it doesn't necessarily
need a process manager connection and if
you use Apple events and you're linking
and application services you can get by
without any without doing any user
interaction user interaction is sort of
at the carbon or cocoa layer but if you
linking its application services you can
get by with writing a demon or writing a
background process that uses apple event
there's a lot of the predefined apple
events that you can implement and back
in the old days this is called the
required for apple event print quit save
something else anything so there are a
lot of appli- you could implement the
scripting sessions which i guess the
apple succession was yesterday would
have been the place to sort of
understand how to implement grifting
behaviors for your application in terms
of factoring your applications for
script ability I would go back and
review slides from previous years wwc
for that a couple of things to know
about op lavance their stateless between
instances of events that you receive the
apple event managers you know it doesn't
care about you it doesn't stop
data for you but most importantly it
allows for scripting so when would you
need to use Apple events well between
applications so there are a bunch of
applications on your platform and some
of them do certain things like you know
flow text around an object or print with
certain attributes you can leverage
those applications because they accept
the Apple events that allow you to
program that behavior so between
applications this is a great thing so
how do you discover an application that
you can talk to in Jaguar and in
previous it basically was bound to the
process manager applications would check
in with the process manager and the
Apple sent framework would talk to the
process manager to discover okay you
know here's ma CS you're trying to talk
to an application whose signature is ma
CS whoever that is that's great that
happens to be the finder you could also
if you launched an application and
you're giving back its head or cross the
serial number you could target an
application by pidan process serial
number in cancer we've added a new
applicant addressing type type
application bundle ID this basically
replaces signature it's better to send a
comm double that finder then just send
to ma CF if you can get away with
targeting parents are directly but in
Jaguar you had to be a client of the
process manager to discover applications
and you couldn't send Apple events
between sessions well you still can't
send in Panther a papal events between
session we don't really allow that but
we enforce a UID based restriction
between user sessions applications owned
by user a concern to applications owned
by user be there sorry depredations
don't ready sir I can only send two
applications owned by user a
applications can be a restricted
depending to be the exception to this is
that applications owned by root and this
includes demons running in the startup
item space are allowed to send to any
other application on the system that's
registered for apple event this is a
very commonly requested feature for
people that are trying to write apache
plugin they wanted to be able to script
application
and now they'll be able to so Apple
events are well supported very well
supported by both the carbon and Coco
framework and by third-party frameworks
that are built on top of carbon in cocoa
events are received on the run loop and
dispatched two handlers that you have
registered within your application space
events that you send are usually sent
synchronously you sand and then you you
block for a reply that's sort of the
older model there there is a preferred
way to do that which is to wait for a
cute reply you send the event waiting
for a cute reply so often do other
things maybe update your UI put up a
sheet let other windows in your
application work and then when the reply
comes in from the server it's delivered
to you as just another event that you
then associate with the original event
that you sent on the server side when
you receive an event you can suspend it
and then resume it at a later time after
you've done the work that the event
originally requested think you know
about suspension and resumption is that
these live in the carbon framework layer
and may necessitate use your interface
so it's kind of a better model if you
can if you can just deal with the event
right away or set up the communication
so that the original event that came in
had information about how to send a
reply later had some state with it
that's said okay when you're done with
the word send me event back to manage
that asynchronous reply mechanism
yourself so scripting is not something
that comes for free in the carbon
framework you need to implement an AE te
resource this describes the classes the
properties or ivars of the class if you
will and verbs that allows you to
operate on the class it lives in this
resource and then the scripting
implementations get the resource and are
able to present you I to the user to
allow the user to pull out the things
that they care about and plug them
together an interesting way cocoa on the
other hand because the application
framework has so much metadata available
and so much ability to introspect upon
the framework in the application running
allows you to use
actual description of what your
application can do that's a script sweet
file and it will actually generate the
AE te resource for you on the fly this
is again something that talk about it
lengths and probably going back over
previous WBC sizes is better to
understand how to implement the 15 ok so
what is an apple event actually look
like it's a structure it's an eight
light structure it's got a four byte
header as area for byte beta type issues
a four character code and then a data
handle and classic mac OS 9 lamb that
was a real handle and if somebody sent
you data you were expected to
dereference to cast it to whatever you
wanted and then just work with it but
when we did the carbon implementation we
took the opportunity to say it's an
opaque data handle unfortunately we
didn't really enforce that restriction
and so a lot of people ported their apps
to carbon and kept looking in the handle
so when we change that for Jaguar
because we always said we were going to
change it a lot of apps broke so we have
sort of a hacky work around in place but
it's not perfect and you're much better
off using accessors to get into the data
speaking of which there are two new API
of Jaguar AE create desk from external
pointer and 80 get desk data range the
first of these lets you say ok here's an
arbitrarily large blob of memory that
I'd like to send to another application
but I don't want to copy it into the
apple of the manager I promise not to
modify it any time soon it's you know an
image or something that I I got and I
want to send it to some other
application using a crate desk from
external pointer the apple event manager
will tell you when it's done with it
when you dispose of the descriptor it
will it will dekaron a reference count
say ok that descriptors done you can
free it now that will actually avoid
topping the memory into the apple event
manager and because the apple of manager
is built on mock messages it'll avoid
copying all that data into the receiving
applications address space that's really
the way to improve performance for large
messages aight you get the fit of range
does basically what that says in the
past you should look at the data handle
and offset some offset and pull out
a field out of the structure you get
this data range lets you do that without
having to copy the whole buffer to a
local buffer so there's that's sort of
the data type in apple event there are
also lists and records which are lists
of those data types or basically
dictionaries where the key to the
dictionary is another four byte code a
lot of the existing Apple events that
you can send and receive have
well-established parameter orders so the
open Apple event for example has a list
of aliases that you're supposed to open
David's opaque let's see so an apple
event record then is sort of two records
slammed together to AE record slammed
together one is the parameters for the
event that's what people typically are
going to deal with and the other is the
attributes of the event which is where
the event came from what the event ID in
classes it's just is it useful to think
of it as sort of two records planned
together instead of one sort of
mysterious record so when you've
messaged data to another when you when
you perform a send the data is copied
into the other applications address
space it's you know if it is optimized
about then it's optimized to be a
virtual memory copy applicants can be
sent between machines we do this in turn
using the type application URL signature
application signature targeting type
thing target address mate so what that
looks like and this is a horrible ugly
thing but epbc is the scheme for remote
apple event you can optionally add the
user name and password directly to the
outgoing message then the host which is
a required parameter and the app's name
which is a required parameter and then
now we've added for Panther optionally
the user ID and the process ID if those
are present those will be used in order
to direct the apple event that comes in
to a specific session
so in order to do multi-session support
in order to target a specific session
you have to use new ID and pin otherwise
it goes to the I guess the current
console user Panther also adds the new
API a twist remote processors this
provides the data of what processes are
available on a given host this was
something we had back in appletalk days
sorry this is when we met back in nine
days using remote applicants over IP you
would specify the name of the the server
that you want to connect to and it would
list the processes when you can click on
one and bring it back this doesn't
implement the UI behavior this is just
the data behavior you'll have to
implement the UI yourself but you know
it should be trivial to do that any
server is also advertise themselves on
rendezvous so yes we're back to the
appletalk days of being able to browse
machines on your network that have a
program linking turned on so if you need
to do rendezvous lookups you can use
this EBP ccdp thing and it's actually
pretty trivial to use the rendezvous the
API to discover you know ok these
servers have these applications
available so talk about the performance
of a balloon for a second there is a CS
message performance and the apples n
performance is you know it's good it's
right there because it's using the same
underlying mechanisms that the mock
layer provides in comparison the apple
event performance in Cooma was
significantly worse because it was
copying the data between address spaces
every time it was basically linear with
message size so the app 11 performance
in a panther is actually fifty percent
better than jaguars for his number of
messages it could send that doesn't
really show up in this chart at all okay
I'm going to talk briefly about cocoa
distributed objects because this is
another topic for a much larger session
cocoa distributed object allows you to
implement a protocol that says here is
an object it has these behaviors you can
now look at it from your
process in another address space across
the network make method calls upon it or
send get messages and whatever
parameters should pass to it I will
marshal those parameters into into a
stream and send it over a wire it allows
you to provide services for other
applications like the services menu uses
distributed objects in order to
implement a lot of its behaviors so what
you get is a client of distributed
object is an object that looks like an
object that you can work with but method
calls to it messages to it actually go
over a wire and talk to another process
that receives those messages interprets
them and performs an action on a local
object so between processes it's going
to use mass messages typically to
perform this I guess there's also an
option to use pipes directly inter
machine it's going to use socket VIP and
it will automatically register your
object for discovery with rendezvous so
some of the objects that you'll see when
we talk about distribute object there's
NS port this is the object that is
responsible for serializing a request
given a particular transport it's sort
of created with the intention of them
going over a mass message so how should
I see realize this request NS connection
which allows you to discover objects
it's sort of how objects are published
in from your server application this is
bound to run loads but actually if the
port is bound to the run loop that's
sort of the thing that receives the
message is actually bound to the run
loop and then there's the NS proxy
protocol which is actually got two
concrete implementations in a client
application you're going to look at the
Anna distant object client under system
object object and it takes care of using
the port in the connection to serialize
requests on the server side it's called
an NS protocol checker that ensures that
the message that the server receives
adheres to what the server really
intends to publish now this with
sort of the flow of events through
distributed object and is pretty much
self-explanatory once an object is
bended to a client he just makes method
calls to it it slows down that pipe
across ports between processes or
machine boundaries and then ultimately
results in the vended object so finish
talking about distributed objects it
allows you to vend and objected to the
object for other applications to see one
thing to note is that messages that are
sent objective-c objects are synchronous
you block for a reply if something goes
wrong he could be blocked for a long
time so it's possible to set a time out
on a reply and that's probably a good
thing to do you said I time out on the
connection object itself and it's not as
efficient as what's something you could
come up with yourself if you need to
send a particular piece of data to
another application and you need a very
high performance way of doing that you
could probably come up with your own
messaging scheme level leveraged on top
of the apple event CF message forward or
mock boards that's going to be more
efficient than just using distributed
objects on the other hand there are a
lot of resisting distributed objects
conversations taking place so it may
make more sense to use one of those it's
it's a performance versus ability to
leverage the what the framework provides
the decision you're gonna have to make
the surgery objects vended inter-process
have the same restrictions as Apple
events wow it let's say as the same
restrictions at CF message port in that
they're isolated within one session
discoverability is isolated to within
one bootstrap space ok so web services
in puma we introduce web service support
in in the apple event manager of all
places and what this did was serialized
apple event records and container types
into xml and send it along to the server
in jaguar remove this down a level and
made it applicable to
objective-c data types and core
foundation data types to the scalar
values and container types it supports
xmlrpc and soap and still supports Apple
events and Apple script by virtue of
supporting apple event so it's possible
to write an apple script application
that talks to web services not on the
internet and it just reads like any any
message call to any other application
you get back a dictionary with some
high-level constructs in it you can look
at the data as if it were just an apple
open record imperative we've added a
message parsing API so it's now possible
to write servers in web services okay so
how do you invoke a web service the the
thing you want to look for is called a
WS method invocation wrap this is the
point that this is an object that
handles serialization of outgoing
request it's constructed with a schema
and URL the schema specifies xmlrpc or
so the URL is of course the endpoint
that you're going to do the HTTP POST to
get to you then set parameters on it you
you have to tell it the dictionary which
is the parameter list so it's
prepositional so you have to say
parameter 1 value 3 kilometer to value
hello and then the order that those
parameters should be see realized the
reason you have to do both is because
depending on the scheme you use it may
be necessary for the serializer to emit
things in a particular order xml-rpc is
positional it doesn't care about the
name of the parameter it cares about the
positions whereas soap tends to be
prepositional where it cares about the
name but not necessarily the order
however there are some servers that also
require that the order be as specified
in the originating document so adding
the the order parameter when you call
set parameters having the order is very
important so then you just invoke it you
can invoke it synchronously in which
case you'll block until the reply comes
back from the server or you can schedule
it on your run loop and when the reply
comes in you're handed a dictionary the
dictionary contains
either the reply data community was a
result of this operation or it could
contain a fault with information about
what happened what went wrong with this
request so the reply from a web service
invitation is always a dictionary that
you have to look into to extract the
actual reply that you expect okay so how
to write a server it's actually really
simple the server API isn't really a
server it does not listen on any sockets
all it does is it basically filtered a
XML document into a CF dictionary then
which you then implement the sort of
democracy behavior pull out the message
name and do something based on that so
the finger looks for in the new API is
WS protocol handler ramp this is created
with the schema of xml-rpc your soap you
then call copy request dictionary with
this thing you've given it a CF data XML
document that you receives over the wire
and it gives you back a CF dictionary
the CF dictionary has the method name
and it's got the the parameter order and
the parameter list the parador de that
it received so you extract the
parameters from this dictionary you do
something based upon them and then you
call create reply document the two
parameters to create reply document are
the original dictionary passed back by
copy request dictionary that has sort of
meta information about the connection
the name of the message which might be
relevant in forming the reply and then a
CF type which is the type that you wish
to send back to the server so you don't
have to wrap it it doesn't have a it's
not prepositional a position at all it's
just the Ross yes or n s type so you
send a reply document using whatever
server that you're embedding the same
and then you profit because I don't know
that's what they always say on slashdot
ok so there is no real free lunch with
web services discovery there are some
standards that are standardizing sort of
accreting over in the corner
to allow for discovery of web services
but we don't support them yet most of
the time when somebody says you need to
call my web service they're going to
hand you a textual description of what
that web service expects and that's
usually the you know a very easy way to
implement it you just sort of there okay
parameter name this should be this value
Prairie in this society that's sort of
how the xml-rpc community works the sub
community is trying to automate that a
lot more and they have the web services
description language for describing the
messages and the methods that are
available via web services we have a
tool WS makes tons that tries to
understand whistle documents and produce
glue code that sits on top of the web
services core framework so if you
actually view the slides from last year
I run that tool and described and show
how that tool is used to create an
application that queries some web
service and sort of automatically
generating the google code for you okay
so i do have a few minutes to go through
my demo and if I could have demolition
too so one of the things that comes up a
lot is people want to be able to write a
patchy plugins or Apache module to talk
to application so I'm going to use a
couple of technologies that I talked
about today to build this application at
cetaphil so I'll just run through it and
then I'll show you the code so the first
thing is that I have an objective c
application that uses web services to
talk to a host / web services so
someplace clear is a web services server
and it is talking to itunes / apple
event so here's my little application i
get a little drawer here i can open up
these wedges and it's going to send a
request to the server each time i open a
wedge to get the who created the song
the title the track has a name of the
artist so go ahead and everybody likes
polka oh I didn't play a little polka
music you
turned down because it's annoying and so
is usually I've got a little progress
bar here at the bottom that updates it's
actually doing a poll to get that once
every second expires a timer often to
request off through Apache and tries to
sort of update the title and the time I
click stop and oh no an exception
occurred this is a good opportunity to
first mute the sound and then go into
the slip that implements all this so the
way the demo is put together and I'm
actually going to make the demo
available through DTS because it does
show a lot of these technology is that
there is an apple script application
that receives the xml RPC request and
does something based on it so here's you
know a whole bunch of apple script to
play tracks this is probably the easiest
thing to understand when my tool said
plate rack and gave the ID of the track
than willing to play it talks to apache
apache talk to a demon that sent the
apple event on to this script which then
sent the applicant to the itunes to play
the song so i got an exception because i
commented this house save the script
rerun or just quit not work quit we run
the script and when i get back here
right poke is still playing in the
background now i can stop it which i'm
sure everybody's relieved about so
because I'm lemon ubergeek I really
don't wanna take my hands off of the
home row so i have a perl script that
uses one of the pearl xmlrpc things to
call my web service running an apache
and i'm doing this to show sort of what
the message actually looks like so if
I'm going to get these genres it's a
simple call xml-rpc pearl subroutine and
the name of the xml RPC method happens
to be the bundle identifier of that
Apple strict application followed by the
name of the subroutine so the
architecture underneath
that's glued to Apache is actually
general it will allow you to send a
applescript do subroutine command to any
applications that implements Apple
script attached ability on so just you
can demo that real quick so i want to
sort of books and spoke in and i always
liked the songs good song let's go ahead
and play hold up our oh it's all about
the pentium okay so anyway you can see
that the script is just working the same
way as an application they could be
running on linux it to be running on
windows if that's really what web
services is all about having a
heterogeneous environment so I still has
a couple minutes I'm just going to show
you some of the source code that does
all this stuff we're to start let's
start with the depth file for the bridge
code that runs alongside of Apache so
the thing is you don't want to patch you
to be running his route you never want
that so instead Apache looks up a demon
that is running as root that is allowed
to send Apple events into this user's
context the demon implements this single
mass message it takes an input XML
request and an output and it outputs the
xml RPC response the implementation of
that this is what make generated for me
this do message server side stub you can
see that the input parameters are the
address of the blob of data and the size
of the blob of data and then I'm to
supply to it the size of the blob of
data that I'm returning and it's count
meg will actually take care of sending
that response for me then in the Apache
module this is where I'm looking up the
name of the demon right so the Apache
module just it gets instantiate advice
when I go to a specific URL looks at the
name of the demon it has already gotten
the data out of the HTTP POST that make
all my demon right here then you
the CF data stuff to sort of wrap the
the data that comes in and then it gets
its response and it forwards it back out
of patchy and all this and apache deals
with you know setting up the
reconnection accepting you're dealing
with errors etc okay so like i said
we're going to put that on the developer
website so that people can you know
write their own demons you're doing all
this stuff like liquor and with that if
we could have the slides back should I
get slide who sliced thing okay so that
was the demo oh there was a nice build
on that when I forgot to do last time so
showing that you can go and use all
these technologies in various places
this is really how you would architects
such a system you would use web services
to accept incoming events from a from a
heterogeneous environment and use xml
RPC in the parsing ap is to figure out
what the data is and use Apple event to
talk to an application that's providing
some service for you all right so let's
summarize the what we've talked about
today and it was a lot of different
technology pipes and sockets this is
typically for legacy code or for tools
or four things that need stream data
between processes notify this is great
for broadcasting a state change and if
you're writing new code where you might
think you're going to use signal please
use notify instead you'll you know much
prefer it mock message allows you to
write really complex servers and it's
very powerful and it's really at the
core of what r OS does and the best
reference to that is probably the source
coding darwin CS message port is a great
way of doing blobs of data messaging
between applications it's very efficient
and it works really well with all our
framework apple event anytime you can
add apple events to application to make
it more scriptable the attitudes guys
didn't know that I was going to have a
perl script talking to their application
they didn't need to know they just had
to implement the script ability and then
I can come along and leverage the work
they pin and then objective-c
distributed object if you need to
participate in an existing conversation
or if you have a new application that
wants to be able to create a new
conversation objective-c distribution is
a fine way to do that ok so we wrap up
here a couple of sessions i want to
point you at building applications for
managed network environments a lot of
the what is applicable to networking is
applicable to inter process
communication so sort of understanding
networking both in that session and in
CF networking depth which I also highly
recommend you're going to get a much
better understanding about how to write
applications that don't block when they
don't need to and perform what really
well on our platform writing threaded
applications on Mac os10 threads are
really just kind of like another process
sort of the same things are going to
apply to sending a message to another
thread and then something experts
tonight which will all go to so here are
the names of some of the some of the
technology people that you might want to
contact the important thing here is the
URL at the bottom where all this
information ends up being anyway so I
don't expect people to actually be able
to write all these things down reference
librarians it should be interesting
because probably the best book on unix
messaging is going to be the original
unix book by Kernaghan in pike there's a
URL you can go to the order that book
the mock documentation I don't think
Apple for this was any the best
documentation I found on it some post
script files on an ftp server at CMU so
that's where you want to go to learn how
to write mock servers inside macintosh'
IEC talks about Apple events it's a
little dated because you know is written
12 years ago but it's all still
applicable so if you want to understand
Apple events better you should go there
and then the web services documentation
online talks about the Jaguar you guys
there is no documentation up on the new
server API yet it's sort of self
documented by the header filings pretty
easy
you