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