IPC between Apps & Components


#1

Hi everyone,

I have tested how IPC works between Legato components
http://www.legato.io/legato-docs/14_10/componenthello_i_p_c.html#helloIPCDefiningTheAPI

Now, I would like to do it between a Component (working as a Server) and an Application (working as a Client). Make sense?
If not, how can I ‘invoke’ a Component function through an App?

I’ve try to solve it with no success following the next steps:

COMPONENT
The first step was to ‘provide’ the api file through the .cdef of the Component (myComponent):

Also, within the .c file (of the Component), I’ve added the following line:

APPLICATION
Then, in the App (client), I have included a reference of the Component: myApp -> References -> Edit dependencies … -> check myComponent

The next step (here is where I have the problem :confused: ) is to ‘require’ test.api file in the App (client). So, the .adef file looks like this:

requires:
{
	api: { myapi = test.api }
}

The error:

myApp.adef:40: ERROR: Second '.' separator missing in internal interface specification 'test.api'. Should be of the form "exe.component.interface".

Also, I’ve change the .adef file following the above error suggestion:

requires:
{
	api: { myapi = component.MyComponent.myapi }
}

The error:

myApp.adef:40: ERROR: Client-side IPC API interface 'component.MyComponent.myapi' not found in app 'myApp'.  Component instance 'component.MyComponent' does not have a client-side interface named 'myapi'.

What can I do in order to ‘invoke’ a Component function from an App?

Thanks!

Information
Legato Application Framework version: 14.10


#2

Hi, Daniel,

“requires: { api: { … } }” in the .adef file means something different than “requires: { api: { … } }” in a Component.cdef file.

Sorry for the confusion on that point. We are looking at ways to make that clearer. I’ll discuss that later, but first let’s fix your immediate problem.

The main conceptual points to keep in mind are these:

  • Components are ingredients that can be put into applications. They don’t do anything by themselves.
  • Applications can contain executables, and executables can contain Components.

So, what you want to do is

  1. Create two components: a server and a client
  2. Create two executables in your application: a server and a client
  3. Put the server component inside the server executable
  4. Put the client component inside the client executable
  5. Bind the interfaces together using a bindings section inside the .adef.

If you want the server and the client to be two separate applications, you can do that by changing step 2 and step 5.

  1. Create two components: a server and a client
  2. Create two applications (a server and a client) each containing one executable.
  3. Put the server component inside the server executable (in the server application)
  4. Put the client component inside the client executable (in the client application)
  5. Make the server interface into an external interface (accessible by other applications) by adding a “provides: { api: { … } }” section to the server app’s .adef.
  6. Add a binding section to the client application’s .adef to bind the client interface to the server application’s external interface.

Applications themselves cannot use APIs. Only components can. The reason for this is mainly that we haven’t come up with a good way in the .adef to attach interfaces to executables without the .adef becoming pretty messy. We have discussed this internally a few times, but haven’t been really happy with the options we’ve come up with so far. Also, it’s pretty easy to create a component, so it doesn’t seem like a high priority given all the other features people are asking for. :slight_smile:

We’ve recognized that confusion arises due to the fact that we reused the syntax “requires: { api: { … } }” and “provides: { api: { … } }” in the .adef, but the meaning is not the same as it is in the Component.cdef. What we are really trying to do in myApp.adef is say something like, “‘exe.component.interface’ should be made into an external interface for this application, and outside this app (in other apps’ .adefs or in the .sdef) it will be called ‘myApp.X’.” Today, if “exe.component.interface” were a client-side interface, I would do this in myApp.adef as follows:

executables:
{
    exe = ( component )
}

requires:
{
    api:
    {
        X = exe.component.interface
    }
}

But, what we are talking about doing from 15.01 onward is this instead:

executables:
{
    exe = ( component )
}

extern:
{
    X = exe.component.interface
}

Simpler? Obviously. Clearer? You tell me.

I hope this helps…

–Jen


#3

Thank you for your reply!

The fist explanation (comunication between components within the same app) I had already tested (it’s the same like helloIpc project sample).
The second worked for me (IPC between Apps) but I had to do one more step:
Add ‘references’/dependencies of the ‘.api’ owner (the server component) within the clientApp & clientComponent.

But now, I have the doubt if it is the right way or if I had to do it in a different way (for example: include & copy the server api file to the client resources folder)

Thank you again for your good explanation! :smiley: Also, I’ve attached the example created.


#4

Hi, Daniel,

I think it is definitely better if you can have one common .api file that is referred to by both the client and the server, which is what you have done. Copying it would work too, of course, but then you have to remember to update both copies if you make changes.

When using the command-line tools, I would keep the one .api file in another directory, outside of all components and applications. But, I’m not sure there is a nice way to do this with Developer Studio yet (I’m more of a command-line guy, myself).

Anyway, I’m glad it’s working for you now.

–Jen