... | ... | @@ -107,6 +107,7 @@ std::cout << "Received request " << request->get() << std::endl; |
|
|
request->reply("Done");
|
|
|
```
|
|
|
The responder is created with the name "the-responder" to identify it.
|
|
|
The pre-condition for the creation of the responder is that *This* must have been initialized.
|
|
|
Like the return value, it is possible to get the request as **binary** data using the *getBinary()* function or method. It is also possible to reply binary data using the *replyBinary()* method or function.
|
|
|
The requests can also be a **two-part message** and the second part can be get with the *getSecondBinaryPart()* method or function.
|
|
|
|
... | ... | @@ -136,7 +137,7 @@ catch (RemoteException e) { |
|
|
}
|
|
|
```
|
|
|
|
|
|
The requester is created by connecting to the responder named "the-responder" living in the "RespApp" application. Once connected, the requester can send requests and receive the responses.
|
|
|
The requester is created by connecting to the responder named "the-responder" living in the "RespApp" application. Once connected, the requester can send requests and receive the responses. Here again the pre-condition for the creation of the requester is that *This* must have been initialized.
|
|
|
|
|
|
The requester application can terminate unexpectedly whereas the responder is responding to it. In that case the responder may block indefinitely. That is why it is possible to set a timeout in milliseconds:
|
|
|
```cpp
|
... | ... | @@ -155,3 +156,48 @@ You can notice that no port was provided to define the requester and responder. |
|
|
|
|
|
# Publisher/Subscriber
|
|
|
|
|
|
Another useful communication pattern is the publish/subscribe pattern. It allows asynchronous messages from one application to other ones. Let's define a Java application *PubJava* which defines a publisher:
|
|
|
```java
|
|
|
try {
|
|
|
// Create the publisher with name "the-publisher".
|
|
|
Publisher publisher = Publisher.create("the-publisher", 1);
|
|
|
|
|
|
// Synchronize with subscribers.
|
|
|
publisher.waitForSubscribers();
|
|
|
|
|
|
// Send data.
|
|
|
for (int i = 0; i < 100; ++i) {
|
|
|
publisher.send("message " + i);
|
|
|
}
|
|
|
|
|
|
// Terminate the publisher.
|
|
|
publisher.terminate();
|
|
|
}
|
|
|
catch (PublisherCreationException e) {
|
|
|
System.out.println("Publisher error:" + e);
|
|
|
}
|
|
|
```
|
|
|
|
|
|
Here again, *This* must have been initialized before creating the publisher. We provide a synchronization feature with the second argument of the *Publisher.create()* method: the number of subscribers can be provided. The call to *Publisher.waitForSubscribers()* is blocking until the required number of subscribers has been reached. This allows to have subscribers that will receive all the messages. The publisher is *synchronized*.
|
|
|
Default value is 0 and in that case *Publisher.waitForSubscribers()* immediately returns. Then the publisher is *not* synchronized and some messages will be lost.
|
|
|
|
|
|
Let's give an example of a subcriber in C++:
|
|
|
```cpp
|
|
|
// Connect to the app PubApp which hosts a publisher.
|
|
|
std::unique_ptr<application::Instance> publisherApp = server.connect("PubApp");
|
|
|
|
|
|
// Create a subscriber to the application.
|
|
|
std::unique_ptr<coms::Subscriber> subscriber = coms::Subscriber::create(*publisherApp, "publisher");
|
|
|
|
|
|
// Receive data.
|
|
|
while (true) {
|
|
|
std::optional<string> message = subscriber->receive();
|
|
|
|
|
|
// If there is no value then the subscriber will not receive message any more.
|
|
|
if (!message.has_value()) {
|
|
|
break;
|
|
|
}
|
|
|
std::cout << "Received " << message.value() << std::endl;
|
|
|
}
|
|
|
```
|
|
|
|