The IPC module in GCF makes it possible for you to host objects in your application for communication with other applications AND to invoke methods on objects in other applications. In the following paragraphs we explain how certain key communication scenarios work.
Enabling IPC communication with your application
To allow incoming IPC communication, you should create an instance of GCF::IpcServer and have it listen for incoming requests.
GCF::IpcServer is a subclass of QTcpServer
. The GCF::IpcServer::listen() method basically creates a server socket and listens for incoming socket connection requests. Every connection request received at this socket will be ackowledged and responded.
An application can have any-number of instances of GCF::IpcServer created. Each server should listen on a different port. You can implement your own mechanisms to publish the availablility of servers and communicate that information to client-GCF applications. You can also make use of GCF::IpcServerDiscovery to discover servers in the Local Area Network.
"Exposing" objects for IPC communication
Any object in your application can be made available for IPC communication
- adding the object to the object tree (GCF::ApplicationServices::objectTree()), if the object has not already been added to it.
- setting the
allowmetaaccess
key totrue
against the information key=value map of the object.
The following code snippet shows you how
To mark objects for remote access in the content file, you can
Service method rules
Public invokable (signal, slot and Q_INVOKABLE) methods in a "exposed" object can be remotely invoked by other applications. Such methods are called "service methods". Service methods have to adhere to the following rules
- Method name must be unabiguous. No two service methods must have the same name, even though C++ allows for method overloading.
- Method parameters can be of type:
int
,bool
,double
,QString
,QStringList
,QVariant
,QVariantList
,QVariantMap
orQByteArray
. All other types must be represented in terms of these types. NOTE: Custom types can be registered usingqRegisterMetaType
and their streaming operators can be registered usingqRegisterMetaTypeStreamOperators
. Such types can be accepted asQVariant
. Example:struct MyType { ... };// Register the typeqRegisterMetaType<MyType>("MyType");// Register streaming operators for the typeQDataStream &operator<<(QDataStream &out, const MyType &myObj) { ... }QDataStream &operator>>(QDataStream &in, MyType &myObj) { ... }qRegisterMetaTypeStreamOperators<MyType>("MyType");class MyClass : public QObject{Q_OBJECTpublic:// ...Q_INVOKABLE GCF::Result serviceMethod(const QVariant& arg) {MyType type = arg.value<MyType>();return this->method(type);}GCF::Result method(const MyType &type) { ... }// ...};
- Return types can be
void
,int
,bool
,double
,QString
,QStringList
,QVariant
,QVariantList
,QVariantMap
,QByteArray
or GCF::Result.
- Methods should return fast. They should never consume more than 60 seconds of clock time. If they do take longer than that, then callers should be made aware of that and they should adjust their call timeout using GCF::IpcCall::setTimeoutDuration().
Invoking service methods
To invoke a service method, you can make use of the GCF::IpcCall class. One instance of this class can be used to make only one service call. Example:
The GCF::IpcCall class always works in asynchronous mode. To use the class in blocking mode you can make use of the GCF::IpcCall::waitForDone() method on the call object. This method waits for the call to complete before it returns. The function returns true if the call was successful, false otherwise. NOTE: the waitForDone()
method waits for a 10 seconds (or a value set using GCF::IpcCall::setTimeoutDuration()). Example:
Signal/Slot connections across applications
You can make use of GCF::IpcRemoteObject to maintain a persistent connection with a remote object. Signal/Slot connections can be made between GCF::IpcRemoteObject and any other object in the application to
- connect signal from a local object to a member (signal or slot) in a remote object
- connect signal from the remote object to a member (signal or slot) in a local object
In addition to remote-signal/slot connections, GCF::IpcRemoteObject can be used to fetch properties of the remote object and also invoke methods on the remote object.
The following code snippet shows you how to create an instance of GCF::IpcRemoteObject and prepare to use it.
You can make use of the GCF::ipcConnect() methods to make signal/slot connections between a local object and remote object. Example:
Discovering remote servers
You can use GCF::IpcServerDiscovery class to discover address and port numbers of GCF::IpcServer objects in GCF applications running on the local-area-network. The following example shows how GCF::IpcServerDiscovery can be used in your applications