17.3. RPC Data Streaming¶
Fast DDS-Gen tool also supports data streaming for function-call based API’s operations in both client and server sides. In this case, the mapping between high-level and low-level API’s is as follows:
On client side, each operation’s input data value corresponds to a Requester’s request sample in the low-level API. Thus, the input data streaming consists of a collection of request samples sent by the Requester to the Replier, representing the Client’s input data that the server needs to process to compute the result of the operation.
On the Server side, each operation’s output data value corresponds to a Replier’s reply sample in the low-level API. Thus, the output data streaming consists of a collection of reply samples sent by the Replier to the Requester, representing the result of the operation that the server sends back to the client.
17.3.1. Data Streaming scenarios¶
Three different scenarios can be considered:
Server side streaming: The client sends a single request to the server, and the server sends multiple replies back to the client associated to the same request.
This is useful when the server needs to send a large amount of data to the client, that cannot be sent in a single reply message.
The collection of reply messages associated to the same request is referred as output data feed. An output data feed is opened when the server sends the first reply message, and closed when the server sends the last reply message, notifying the client that no more reply messages are expected to be received. Each data message can be obtained at the client side by reading this output feed using the Fast DDS-Gen generated API.
Client side streaming: The client sends multiple requests to the server, and the server sends a single reply back to the client, typically after receiving all the client’s messages.
This is useful when the client needs to send a large amount of data to the server, that cannot be sent in a single request message.
The collection of request messages associated to the same reply is referred as input data feed. An input data feed is opened when the client calls the operation method, and closed by the user through the Fast DDS-Gen generated API when all input data has been sent. Users can access the client’s input data at the server side implementation of the interface operations by reading the input feed using the generated API.
Bidirectional streaming: The client sends multiple requests to the server through an input data feed, and the server responds with multiple replies through an output data feed.
As both input and output data feeds are independent from each other, user can customize the server behaviour in the server side’s operations implementation; the server could wait until receiving all the client’s input data (i.e until being notified that the input feed is closed) before sending any reply message (i.e before opening the output feed), or could implement a kind of “ping-pong” operation, sending a message back to the client after receiving each request message.
For more information about how to define an IDL interface for data streaming and further details about handling input and output data feeds, please refer to Data Streaming interfaces and Defining data streaming operations. For more information about how to build data streaming applications using the Fast DDS-Gen tool, see Building a RPC Client/Server application with data streaming.
17.3.2. Data Streaming interfaces¶
Fast DDS provides a set of interfaces to support data streaming in the RPC API, as explained in Data Streaming scenarios. When Fast DDS-Gen generates the source code, they are automatically implemented, so the user can use them directly in an RPC application involving data streaming without additional steps.
17.3.2.1. Server side streaming¶
Output feed is managed using the RpcServerWriter
and RpcClientReader
interfaces,
implemented in the server and client files of the
Fast DDS-Gen generate code, respectively, for each operation defined in the IDL interface.
For each RpcServerWriter
implementation, Fast DDS-Gen stores a reference to a Replier
instance,
which is used to send the reply samples associated to the output feed data.
User can send each computed value to the client by calling write()
.
Specifying when the output data feed is closed is not necessary, as this is done automatically (after finishing
the server-side operation execution)
by the Fast DDS-Gen generated code sending a last reply sample specifying that no more values will be sent.
Similarly, for each RpcClientReader
implementation, Fast DDS-Gen stores a reference
to a Requester
instance, which is used to received the reply samples associated to the output feed data.
When a new sample is received, client stores the value sent by the server internally in a queue,
which can be accessed by the user through the read()
methods. This operation blocks the
thread until a new output feed value is available, or a configured timeout expires.
User can also cancel an active output feed at the client side by calling cancel()
method.
17.3.2.2. Client side streaming¶
Input feed is managed using the RpcClientWriter
and RpcServerReader
interfaces,
implemented in the client files and server files of the
Fast DDS-Gen generated code, respectively, for each operation defined in the IDL interface.
For each RpcClientWriter
implementation, Fast DDS-Gen stores a reference to a Requester
instance,
which is used to send the reply samples associated to the input feed data.
User can send each input data value to the server by calling write()
method,
or close the input feed by calling finish()
method.
Additionally, an RpcStatusCode
can be specified to indicate the reason for closing the input feed.
Note
If no reason is specified in the finish()
method, it is configured to be
RPC_STATUS_CODE_OK
by default.
Similarly, for each RpcServerReader
implementation, Fast DDS-Gen stores a reference
to a Replier
instance, which is used to received the request samples associated to the input feed data.
When a new sample is received, server stores the value sent by the client internally in a queue,
which can be accessed by the user through the read()
methods. This operation blocks the
thread until a new input feed value is available, or a configured timeout expires.
17.3.2.3. Bidirectional streaming¶
Bidirectional streaming uses independent input and output feeds, so they can be managed separately using the interfaces of the previous cases.