blob: cc000e76d3bdfe1ed43265b0c1d06b9573a3dc3a [file] [log] [blame]
Alexei Frolov26e3ae62020-05-04 17:06:17 -07001.. default-domain:: cpp
2
3.. highlight:: sh
4
5.. _chapter-pw-rpc:
6
7------
8pw_rpc
9------
10The ``pw_rpc`` module provides a system for defining and invoking remote
11procedure calls (RPCs) on a device.
12
13.. note::
14
15 Under construction.
Wyatt Hepler948f5472020-06-02 16:52:28 -070016
17RPC server
18==========
19Declare an instance of ``rpc::Server`` and register services with it.
20
21.. admonition:: TODO
22
23 Document the public interface
24
25RPC server implementation
26-------------------------
27
28The Method class
29^^^^^^^^^^^^^^^^
30The RPC Server depends on the ``pw::rpc::internal::Method`` class. ``Method``
31serves as the bridge between the ``pw_rpc`` server library and the user-defined
32RPC functions. ``Method`` takes an RPC packet, decodes it using a protobuf
33library (if applicable), and calls the RPC function. Since ``Method`` interacts
34directly with the protobuf library, it must be implemented separately for each
35protobuf library.
36
37``pw::rpc::internal::Method`` is not implemented as a facade with different
38backends. Instead, there is a separate instance of the ``pw_rpc`` server library
39for each ``Method`` implementation. There are a few reasons for this.
40
41* ``Method`` is entirely internal to ``pw_rpc``. Users will never implement a
42 custom backend. Exposing a facade would unnecessarily expose implementation
43 details and make ``pw_rpc`` more difficult to use.
44* There is no common interface between ``pw_rpc`` / ``Method`` implementations.
45 It's not possible to swap between e.g. a Nanopb and a ``pw_protobuf`` RPC
46 server because the interface for the user-implemented RPCs changes completely.
47 This nullifies the primary benefit of facades.
48* The different ``Method`` implementations can be built easily alongside one
49 another in a cross-platform way. This makes testing simpler, since the tests
50 build with any backend configuration. Users can select which ``Method``
51 implementation to use simply by depending on the corresponding server library.
52
53Packet flow
54^^^^^^^^^^^
55
56Requests
57~~~~~~~~
58
59.. blockdiag::
60
61 blockdiag {
62 packets [shape = beginpoint];
63
64 group {
65 label = "pw_rpc library"
66
67 server [label = "Server"];
68 service [label = "internal::Service"];
69 method [label = "internal::Method"];
70 }
71
72 stubs [label = "generated services", shape = ellipse];
73 user [label = "user-defined RPCs", shape = roundedbox];
74
75 packets -> server -> service -> method -> stubs -> user;
76 packets -> server [folded];
77 method -> stubs [folded];
78 }
79
80Responses
81~~~~~~~~~
82
83.. blockdiag::
84
85 blockdiag {
86 user -> stubs [folded];
87
88 group {
89 label = "pw_rpc library"
90
91 server [label = "Server"];
92 method [label = "internal::Method"];
93 channel [label = "Channel"];
94 }
95
96 stubs [label = "generated services", shape = ellipse];
97 user [label = "user-defined RPCs", shape = roundedbox];
98 packets [shape = beginpoint];
99
100 user -> stubs -> method [folded];
101 method -> server -> channel;
102 channel -> packets [folded];
103 }