| cannam@133 | 1 --- | 
| cannam@133 | 2 layout: page | 
| cannam@133 | 3 title: C++ RPC | 
| cannam@133 | 4 --- | 
| cannam@133 | 5 | 
| cannam@133 | 6 # C++ RPC | 
| cannam@133 | 7 | 
| cannam@133 | 8 The Cap'n Proto C++ RPC layer sits on top of the [serialization layer](cxx.html) and implements | 
| cannam@133 | 9 the [RPC protocol](rpc.html). | 
| cannam@133 | 10 | 
| cannam@133 | 11 ## Current Status | 
| cannam@133 | 12 | 
| cannam@133 | 13 As of version 0.4, Cap'n Proto's C++ RPC implementation is a [Level 1](rpc.html#protocol-features) | 
| cannam@133 | 14 implementation.  Persistent capabilities, three-way introductions, and distributed equality are | 
| cannam@133 | 15 not yet implemented. | 
| cannam@133 | 16 | 
| cannam@133 | 17 ## Sample Code | 
| cannam@133 | 18 | 
| cannam@133 | 19 The [Calculator example](https://github.com/sandstorm-io/capnproto/tree/master/c++/samples) implements | 
| cannam@133 | 20 a fully-functional Cap'n Proto client and server. | 
| cannam@133 | 21 | 
| cannam@133 | 22 ## KJ Concurrency Framework | 
| cannam@133 | 23 | 
| cannam@133 | 24 RPC naturally requires a notion of concurrency.  Unfortunately, | 
| cannam@133 | 25 [all concurrency models suck](https://plus.google.com/u/0/+KentonVarda/posts/D95XKtB5DhK). | 
| cannam@133 | 26 | 
| cannam@133 | 27 Cap'n Proto's RPC is based on the [KJ library](cxx.html#kj-library)'s event-driven concurrency | 
| cannam@133 | 28 framework.  The core of the KJ asynchronous framework (events, promises, callbacks) is defined in | 
| cannam@133 | 29 `kj/async.h`, with I/O interfaces (streams, sockets, networks) defined in `kj/async-io.h`. | 
| cannam@133 | 30 | 
| cannam@133 | 31 ### Event Loop Concurrency | 
| cannam@133 | 32 | 
| cannam@133 | 33 KJ's concurrency model is based on event loops.  While multiple threads are allowed, each thread | 
| cannam@133 | 34 must have its own event loop.  KJ discourages fine-grained interaction between threads as | 
| cannam@133 | 35 synchronization is expensive and error-prone.  Instead, threads are encouraged to communicate | 
| cannam@133 | 36 through Cap'n Proto RPC. | 
| cannam@133 | 37 | 
| cannam@133 | 38 KJ's event loop model bears a lot of similarity to the Javascript concurrency model.  Experienced | 
| cannam@133 | 39 Javascript hackers -- especially node.js hackers -- will feel right at home. | 
| cannam@133 | 40 | 
| cannam@133 | 41 _As of version 0.4, the only supported way to communicate between threads is over pipes or | 
| cannam@133 | 42 socketpairs.  This will be improved in future versions.  For now, just set up an RPC connection | 
| cannam@133 | 43 over that socketpair.  :)_ | 
| cannam@133 | 44 | 
| cannam@133 | 45 ### Promises | 
| cannam@133 | 46 | 
| cannam@133 | 47 Function calls that do I/O must do so asynchronously, and must return a "promise" for the | 
| cannam@133 | 48 result.  Promises -- also known as "futures" in some systems -- are placeholders for the results | 
| cannam@133 | 49 of operations that have not yet completed.  When the operation completes, we say that the promise | 
| cannam@133 | 50 "resolves" to a value, or is "fulfilled".  A promise can also be "rejected", which means an | 
| cannam@133 | 51 exception occurred. | 
| cannam@133 | 52 | 
| cannam@133 | 53 {% highlight c++ %} | 
| cannam@133 | 54 // Example promise-based interfaces. | 
| cannam@133 | 55 | 
| cannam@133 | 56 kj::Promise<kj::String> fetchHttp(kj::StringPtr url); | 
| cannam@133 | 57 // Asynchronously fetches an HTTP document and returns | 
| cannam@133 | 58 // the content as a string. | 
| cannam@133 | 59 | 
| cannam@133 | 60 kj::Promise<void> sendEmail(kj::StringPtr address, | 
| cannam@133 | 61     kj::StringPtr title, kj::StringPtr body); | 
| cannam@133 | 62 // Sends an e-mail to the given address with the given title | 
| cannam@133 | 63 // and body.  The returned promise resolves (to nothing) when | 
| cannam@133 | 64 // the message has been successfully sent. | 
| cannam@133 | 65 {% endhighlight %} | 
| cannam@133 | 66 | 
| cannam@133 | 67 As you will see, KJ promises are very similar to the evolving Javascript promise standard, and | 
| cannam@133 | 68 much of the [wisdom around it](https://www.google.com/search?q=javascript+promises) can be directly | 
| cannam@133 | 69 applied to KJ promises. | 
| cannam@133 | 70 | 
| cannam@133 | 71 ### Callbacks | 
| cannam@133 | 72 | 
| cannam@133 | 73 If you want to do something with the result of a promise, you must first wait for it to complete. | 
| cannam@133 | 74 This is normally done by registering a callback to execute on completion.  Luckily, C++11 just | 
| cannam@133 | 75 introduced lambdas, which makes this far more pleasant than it would have been a few years ago! | 
| cannam@133 | 76 | 
| cannam@133 | 77 {% highlight c++ %} | 
| cannam@133 | 78 kj::Promise<kj::String> contentPromise = | 
| cannam@133 | 79     fetchHttp("http://example.com"); | 
| cannam@133 | 80 | 
| cannam@133 | 81 kj::Promise<int> lineCountPromise = | 
| cannam@133 | 82     contentPromise.then([](kj::String&& content) { | 
| cannam@133 | 83   return countChars(content, '\n'); | 
| cannam@133 | 84 }); | 
| cannam@133 | 85 {% endhighlight %} | 
| cannam@133 | 86 | 
| cannam@133 | 87 The callback passed to `then()` takes the promised result as its parameter and returns a new value. | 
| cannam@133 | 88 `then()` itself returns a new promise for that value which the callback will eventually return. | 
| cannam@133 | 89 If the callback itself returns a promise, then `then()` actually returns a promise for the | 
| cannam@133 | 90 resolution of the latter promise -- that is, `Promise<Promise<T>>` is automatically reduced to | 
| cannam@133 | 91 `Promise<T>`. | 
| cannam@133 | 92 | 
| cannam@133 | 93 Note that `then()` consumes the original promise:  you can only call `then()` once.  This is true | 
| cannam@133 | 94 of all of the methods of `Promise`.  The only way to consume a promise in multiple places is to | 
| cannam@133 | 95 first "fork" it with the `fork()` method, which we don't get into here.  Relatedly, promises | 
| cannam@133 | 96 are linear types, which means they have move constructors but not copy constructors. | 
| cannam@133 | 97 | 
| cannam@133 | 98 ### Error Propagation | 
| cannam@133 | 99 | 
| cannam@133 | 100 `then()` takes an optional second parameter for handling errors.  Think of this like a `catch` | 
| cannam@133 | 101 block. | 
| cannam@133 | 102 | 
| cannam@133 | 103 {% highlight c++ %} | 
| cannam@133 | 104 kj::Promise<int> lineCountPromise = | 
| cannam@133 | 105     promise.then([](kj::String&& content) { | 
| cannam@133 | 106   return countChars(content, '\n'); | 
| cannam@133 | 107 }, [](kj::Exception&& exception) { | 
| cannam@133 | 108   // Error!  Pretend the document was empty. | 
| cannam@133 | 109   return 0; | 
| cannam@133 | 110 }); | 
| cannam@133 | 111 {% endhighlight %} | 
| cannam@133 | 112 | 
| cannam@133 | 113 Note that the KJ framework coerces all exceptions to `kj::Exception` -- the exception's description | 
| cannam@133 | 114 (as returned by `what()`) will be retained, but any type-specific information is lost.  Under KJ | 
| cannam@133 | 115 exception philosophy, exceptions always represent an error that should not occur under normal | 
| cannam@133 | 116 operation, and the only purpose of exceptions is to make software fault-tolerant.  In particular, | 
| cannam@133 | 117 the only reasonable ways to handle an exception are to try again, tell a human, and/or propagate | 
| cannam@133 | 118 to the caller.  To that end, `kj::Exception` contains information useful for reporting purposes | 
| cannam@133 | 119 and to help decide if trying again is reasonable, but typed exception hierarchies are not useful | 
| cannam@133 | 120 and not supported. | 
| cannam@133 | 121 | 
| cannam@133 | 122 It is recommended that Cap'n Proto code use the assertion macros in `kj/debug.h` to throw | 
| cannam@133 | 123 exceptions rather than use the C++ `throw` keyword.  These macros make it easy to add useful | 
| cannam@133 | 124 debug information to an exception and generally play nicely with the KJ framework.  In fact, you | 
| cannam@133 | 125 can even use these macros -- and propagate exceptions through promises -- if you compile your code | 
| cannam@133 | 126 with exceptions disabled.  See the headers for more information. | 
| cannam@133 | 127 | 
| cannam@133 | 128 ### Waiting | 
| cannam@133 | 129 | 
| cannam@133 | 130 It is illegal for code running in an event callback to wait, since this would stall the event loop. | 
| cannam@133 | 131 However, if you are the one responsible for starting the event loop in the first place, then KJ | 
| cannam@133 | 132 makes it easy to say "run the event loop until this promise resolves, then return the result". | 
| cannam@133 | 133 | 
| cannam@133 | 134 {% highlight c++ %} | 
| cannam@133 | 135 kj::EventLoop loop; | 
| cannam@133 | 136 kj::WaitScope waitScope(loop); | 
| cannam@133 | 137 | 
| cannam@133 | 138 kj::Promise<kj::String> contentPromise = | 
| cannam@133 | 139     fetchHttp("http://example.com"); | 
| cannam@133 | 140 | 
| cannam@133 | 141 kj::String content = contentPromise.wait(waitScope); | 
| cannam@133 | 142 | 
| cannam@133 | 143 int lineCount = countChars(content, '\n'); | 
| cannam@133 | 144 {% endhighlight %} | 
| cannam@133 | 145 | 
| cannam@133 | 146 Using `wait()` is common in high-level client-side code.  On the other hand, it is almost never | 
| cannam@133 | 147 used in servers. | 
| cannam@133 | 148 | 
| cannam@133 | 149 ### Cancellation | 
| cannam@133 | 150 | 
| cannam@133 | 151 If you discard a `Promise` without calling any of its methods, the operation it was waiting for | 
| cannam@133 | 152 is canceled, because the `Promise` itself owns that operation.  This means than any pending | 
| cannam@133 | 153 callbacks simply won't be executed.  If you need explicit notification when a promise is canceled, | 
| cannam@133 | 154 you can use its `attach()` method to attach an object with a destructor -- the destructor will be | 
| cannam@133 | 155 called when the promise either completes or is canceled. | 
| cannam@133 | 156 | 
| cannam@133 | 157 ### Other Features | 
| cannam@133 | 158 | 
| cannam@133 | 159 KJ supports a number of primitive operations that can be performed on promises.  The complete API | 
| cannam@133 | 160 is documented directly in the `kj/async.h` header.  Additionally, see the `kj/async-io.h` header | 
| cannam@133 | 161 for APIs for performing basic network I/O -- although Cap'n Proto RPC users typically won't need | 
| cannam@133 | 162 to use these APIs directly. | 
| cannam@133 | 163 | 
| cannam@133 | 164 ## Generated Code | 
| cannam@133 | 165 | 
| cannam@133 | 166 Imagine the following interface: | 
| cannam@133 | 167 | 
| cannam@133 | 168 {% highlight capnp %} | 
| cannam@133 | 169 interface Directory { | 
| cannam@133 | 170   create @0 (name :Text) -> (file :File); | 
| cannam@133 | 171   open @1 (name :Text) -> (file :File); | 
| cannam@133 | 172   remove @2 (name :Text); | 
| cannam@133 | 173 } | 
| cannam@133 | 174 {% endhighlight %} | 
| cannam@133 | 175 | 
| cannam@133 | 176 `capnp compile` will generate code that looks like this (edited for readability): | 
| cannam@133 | 177 | 
| cannam@133 | 178 {% highlight c++ %} | 
| cannam@133 | 179 struct Directory { | 
| cannam@133 | 180   Directory() = delete; | 
| cannam@133 | 181 | 
| cannam@133 | 182   class Client; | 
| cannam@133 | 183   class Server; | 
| cannam@133 | 184 | 
| cannam@133 | 185   struct CreateParams; | 
| cannam@133 | 186   struct CreateResults; | 
| cannam@133 | 187   struct OpenParams; | 
| cannam@133 | 188   struct OpenResults; | 
| cannam@133 | 189   struct RemoveParams; | 
| cannam@133 | 190   struct RemoveResults; | 
| cannam@133 | 191   // Each of these is equivalent to what would be generated for | 
| cannam@133 | 192   // a Cap'n Proto struct with one field for each parameter / | 
| cannam@133 | 193   // result. | 
| cannam@133 | 194 }; | 
| cannam@133 | 195 | 
| cannam@133 | 196 class Directory::Client | 
| cannam@133 | 197     : public virtual capnp::Capability::Client { | 
| cannam@133 | 198 public: | 
| cannam@133 | 199   Client(std::nullptr_t); | 
| cannam@133 | 200   Client(kj::Own<Directory::Server> server); | 
| cannam@133 | 201   Client(kj::Promise<Client> promise); | 
| cannam@133 | 202   Client(kj::Exception exception); | 
| cannam@133 | 203 | 
| cannam@133 | 204   capnp::Request<CreateParams, CreateResults> createRequest(); | 
| cannam@133 | 205   capnp::Request<OpenParams, OpenResults> openRequest(); | 
| cannam@133 | 206   capnp::Request<RemoveParams, RemoveResults> removeRequest(); | 
| cannam@133 | 207 }; | 
| cannam@133 | 208 | 
| cannam@133 | 209 class Directory::Server | 
| cannam@133 | 210     : public virtual capnp::Capability::Server { | 
| cannam@133 | 211 protected: | 
| cannam@133 | 212   typedef capnp::CallContext<CreateParams, CreateResults> CreateContext; | 
| cannam@133 | 213   typedef capnp::CallContext<OpenParams, OpenResults> OpenContext; | 
| cannam@133 | 214   typedef capnp::CallContext<RemoveParams, RemoveResults> RemoveContext; | 
| cannam@133 | 215   // Convenience typedefs. | 
| cannam@133 | 216 | 
| cannam@133 | 217   virtual kj::Promise<void> create(CreateContext context); | 
| cannam@133 | 218   virtual kj::Promise<void> open(OpenContext context); | 
| cannam@133 | 219   virtual kj::Promise<void> remove(RemoveContext context); | 
| cannam@133 | 220   // Methods for you to implement. | 
| cannam@133 | 221 }; | 
| cannam@133 | 222 {% endhighlight %} | 
| cannam@133 | 223 | 
| cannam@133 | 224 ### Clients | 
| cannam@133 | 225 | 
| cannam@133 | 226 The generated `Client` type represents a reference to a remote `Server`.  `Client`s are | 
| cannam@133 | 227 pass-by-value types that use reference counting under the hood.  (Warning:  For performance | 
| cannam@133 | 228 reasons, the reference counting used by `Client`s is not thread-safe, so you must not copy a | 
| cannam@133 | 229 `Client` to another thread, unless you do it by means of an inter-thread RPC.) | 
| cannam@133 | 230 | 
| cannam@133 | 231 A `Client` can be implicitly constructed from any of: | 
| cannam@133 | 232 | 
| cannam@133 | 233 * A `kj::Own<Server>`, which takes ownership of the server object and creates a client that | 
| cannam@133 | 234   calls it.  (You can get a `kj::Own<T>` to a newly-allocated heap object using | 
| cannam@133 | 235   `kj::heap<T>(constructorParams)`; see `kj/memory.h`.) | 
| cannam@133 | 236 * A `kj::Promise<Client>`, which creates a client whose methods first wait for the promise to | 
| cannam@133 | 237   resolve, then forward the call to the resulting client. | 
| cannam@133 | 238 * A `kj::Exception`, which creates a client whose methods always throw that exception. | 
| cannam@133 | 239 * `nullptr`, which creates a client whose methods always throw.  This is meant to be used to | 
| cannam@133 | 240   initialize variables that will be initialized to a real value later on. | 
| cannam@133 | 241 | 
| cannam@133 | 242 For each interface method `foo()`, the `Client` has a method `fooRequest()` which creates a new | 
| cannam@133 | 243 request to call `foo()`.  The returned `capnp::Request` object has methods equivalent to a | 
| cannam@133 | 244 `Builder` for the parameter struct (`FooParams`), with the addition of a method `send()`. | 
| cannam@133 | 245 `send()` sends the RPC and returns a `capnp::RemotePromise<FooResults>`. | 
| cannam@133 | 246 | 
| cannam@133 | 247 This `RemotePromise` is equivalent to `kj::Promise<capnp::Response<FooResults>>`, but also has | 
| cannam@133 | 248 methods that allow pipelining.  Namely: | 
| cannam@133 | 249 | 
| cannam@133 | 250 * For each interface-typed result, it has a getter method which returns a `Client` of that type. | 
| cannam@133 | 251   Calling this client will send a pipelined call to the server. | 
| cannam@133 | 252 * For each struct-typed result, it has a getter method which returns an object containing pipeline | 
| cannam@133 | 253   getters for that struct's fields. | 
| cannam@133 | 254 | 
| cannam@133 | 255 In other words, the `RemotePromise` effectively implements a subset of the eventual results' | 
| cannam@133 | 256 `Reader` interface -- one that only allows access to interfaces and sub-structs. | 
| cannam@133 | 257 | 
| cannam@133 | 258 The `RemotePromise` eventually resolves to `capnp::Response<FooResults>`, which behaves like a | 
| cannam@133 | 259 `Reader` for the result struct except that it also owns the result message. | 
| cannam@133 | 260 | 
| cannam@133 | 261 {% highlight c++ %} | 
| cannam@133 | 262 Directory::Client dir = ...; | 
| cannam@133 | 263 | 
| cannam@133 | 264 // Create a new request for the `open()` method. | 
| cannam@133 | 265 auto request = dir.openRequest(); | 
| cannam@133 | 266 request.setName("foo"); | 
| cannam@133 | 267 | 
| cannam@133 | 268 // Send the request. | 
| cannam@133 | 269 auto promise = request.send(); | 
| cannam@133 | 270 | 
| cannam@133 | 271 // Make a pipelined request. | 
| cannam@133 | 272 auto promise2 = promise.getFile().getSizeRequest().send(); | 
| cannam@133 | 273 | 
| cannam@133 | 274 // Wait for the full results. | 
| cannam@133 | 275 auto promise3 = promise2.then( | 
| cannam@133 | 276     [](capnp::Response<File::GetSizeResults>&& response) { | 
| cannam@133 | 277   cout << "File size is: " << response.getSize() << endl; | 
| cannam@133 | 278 }); | 
| cannam@133 | 279 {% endhighlight %} | 
| cannam@133 | 280 | 
| cannam@133 | 281 For [generic methods](language.html#generic-methods), the `fooRequest()` method will be a template; | 
| cannam@133 | 282 you must explicitly specify type parameters. | 
| cannam@133 | 283 | 
| cannam@133 | 284 ### Servers | 
| cannam@133 | 285 | 
| cannam@133 | 286 The generated `Server` type is an abstract interface which may be subclassed to implement a | 
| cannam@133 | 287 capability.  Each method takes a `context` argument and returns a `kj::Promise<void>` which | 
| cannam@133 | 288 resolves when the call is finished.  The parameter and result structures are accessed through the | 
| cannam@133 | 289 context -- `context.getParams()` returns a `Reader` for the parameters, and `context.getResults()` | 
| cannam@133 | 290 returns a `Builder` for the results.  The context also has methods for controlling RPC logistics, | 
| cannam@133 | 291 such as cancellation -- see `capnp::CallContext` in `capnp/capability.h` for details. | 
| cannam@133 | 292 | 
| cannam@133 | 293 Accessing the results through the context (rather than by returning them) is unintuitive, but | 
| cannam@133 | 294 necessary because the underlying RPC transport needs to have control over where the results are | 
| cannam@133 | 295 allocated.  For example, a zero-copy shared memory transport would need to allocate the results in | 
| cannam@133 | 296 the shared memory segment.  Hence, the method implementation cannot just create its own | 
| cannam@133 | 297 `MessageBuilder`. | 
| cannam@133 | 298 | 
| cannam@133 | 299 {% highlight c++ %} | 
| cannam@133 | 300 class DirectoryImpl final: public Directory::Server { | 
| cannam@133 | 301 public: | 
| cannam@133 | 302   kj::Promise<void> open(OpenContext context) override { | 
| cannam@133 | 303     auto iter = files.find(context.getParams().getName()); | 
| cannam@133 | 304 | 
| cannam@133 | 305     // Throw an exception if not found. | 
| cannam@133 | 306     KJ_REQUIRE(iter != files.end(), "File not found."); | 
| cannam@133 | 307 | 
| cannam@133 | 308     context.getResults().setFile(iter->second); | 
| cannam@133 | 309 | 
| cannam@133 | 310     return kj::READY_NOW; | 
| cannam@133 | 311   } | 
| cannam@133 | 312 | 
| cannam@133 | 313   // Any method which we don't implement will simply throw | 
| cannam@133 | 314   // an exception by default. | 
| cannam@133 | 315 | 
| cannam@133 | 316 private: | 
| cannam@133 | 317   std::map<kj::StringPtr, File::Client> files; | 
| cannam@133 | 318 }; | 
| cannam@133 | 319 {% endhighlight %} | 
| cannam@133 | 320 | 
| cannam@133 | 321 On the server side, [generic methods](language.html#generic-methods) are NOT templates. Instead, | 
| cannam@133 | 322 the generated code is exactly as if all of the generic parameters were bound to `AnyPointer`. The | 
| cannam@133 | 323 server generally does not get to know exactly what type the client requested; it must be designed | 
| cannam@133 | 324 to be correct for any parameterization. | 
| cannam@133 | 325 | 
| cannam@133 | 326 ## Initializing RPC | 
| cannam@133 | 327 | 
| cannam@133 | 328 Cap'n Proto makes it easy to start up an RPC client or server using the  "EZ RPC" classes, | 
| cannam@133 | 329 defined in `capnp/ez-rpc.h`.  These classes get you up and running quickly, but they hide a lot | 
| cannam@133 | 330 of details that power users will likely want to manipulate.  Check out the comments in `ez-rpc.h` | 
| cannam@133 | 331 to understand exactly what you get and what you miss.  For the purpose of this overview, we'll | 
| cannam@133 | 332 show you how to use EZ RPC to get started. | 
| cannam@133 | 333 | 
| cannam@133 | 334 ### Starting a client | 
| cannam@133 | 335 | 
| cannam@133 | 336 A client should typically look like this: | 
| cannam@133 | 337 | 
| cannam@133 | 338 {% highlight c++ %} | 
| cannam@133 | 339 #include <capnp/ez-rpc.h> | 
| cannam@133 | 340 #include "my-interface.capnp.h" | 
| cannam@133 | 341 #include <iostream> | 
| cannam@133 | 342 | 
| cannam@133 | 343 int main(int argc, const char* argv[]) { | 
| cannam@133 | 344   // We expect one argument specifying the server address. | 
| cannam@133 | 345   if (argc != 2) { | 
| cannam@133 | 346     std::cerr << "usage: " << argv[0] << " HOST[:PORT]" << std::endl; | 
| cannam@133 | 347     return 1; | 
| cannam@133 | 348   } | 
| cannam@133 | 349 | 
| cannam@133 | 350   // Set up the EzRpcClient, connecting to the server on port | 
| cannam@133 | 351   // 5923 unless a different port was specified by the user. | 
| cannam@133 | 352   capnp::EzRpcClient client(argv[1], 5923); | 
| cannam@133 | 353   auto& waitScope = client.getWaitScope(); | 
| cannam@133 | 354 | 
| cannam@133 | 355   // Request the bootstrap capability from the server. | 
| cannam@133 | 356   MyInterface::Client cap = client.getMain<MyInterface>(); | 
| cannam@133 | 357 | 
| cannam@133 | 358   // Make a call to the capability. | 
| cannam@133 | 359   auto request = cap.fooRequest(); | 
| cannam@133 | 360   request.setParam(123); | 
| cannam@133 | 361   auto promise = request.send(); | 
| cannam@133 | 362 | 
| cannam@133 | 363   // Wait for the result.  This is the only line that blocks. | 
| cannam@133 | 364   auto response = promise.wait(waitScope); | 
| cannam@133 | 365 | 
| cannam@133 | 366   // All done. | 
| cannam@133 | 367   std::cout << response.getResult() << std::endl; | 
| cannam@133 | 368   return 0; | 
| cannam@133 | 369 } | 
| cannam@133 | 370 {% endhighlight %} | 
| cannam@133 | 371 | 
| cannam@133 | 372 Note that for the connect address, Cap'n Proto supports DNS host names as well as IPv4 and IPv6 | 
| cannam@133 | 373 addresses.  Additionally, a Unix domain socket can be specified as `unix:` followed by a path name. | 
| cannam@133 | 374 | 
| cannam@133 | 375 For a more complete example, see the | 
| cannam@133 | 376 [calculator client sample](https://github.com/sandstorm-io/capnproto/tree/master/c++/samples/calculator-client.c++). | 
| cannam@133 | 377 | 
| cannam@133 | 378 ### Starting a server | 
| cannam@133 | 379 | 
| cannam@133 | 380 A server might look something like this: | 
| cannam@133 | 381 | 
| cannam@133 | 382 {% highlight c++ %} | 
| cannam@133 | 383 #include <capnp/ez-rpc.h> | 
| cannam@133 | 384 #include "my-interface-impl.h" | 
| cannam@133 | 385 #include <iostream> | 
| cannam@133 | 386 | 
| cannam@133 | 387 int main(int argc, const char* argv[]) { | 
| cannam@133 | 388   // We expect one argument specifying the address to which | 
| cannam@133 | 389   // to bind and accept connections. | 
| cannam@133 | 390   if (argc != 2) { | 
| cannam@133 | 391     std::cerr << "usage: " << argv[0] << " ADDRESS[:PORT]" | 
| cannam@133 | 392               << std::endl; | 
| cannam@133 | 393     return 1; | 
| cannam@133 | 394   } | 
| cannam@133 | 395 | 
| cannam@133 | 396   // Set up the EzRpcServer, binding to port 5923 unless a | 
| cannam@133 | 397   // different port was specified by the user.  Note that the | 
| cannam@133 | 398   // first parameter here can be any "Client" object or anything | 
| cannam@133 | 399   // that can implicitly cast to a "Client" object.  You can even | 
| cannam@133 | 400   // re-export a capability imported from another server. | 
| cannam@133 | 401   capnp::EzRpcServer server(kj::heap<MyInterfaceImpl>(), argv[1], 5923); | 
| cannam@133 | 402   auto& waitScope = server.getWaitScope(); | 
| cannam@133 | 403 | 
| cannam@133 | 404   // Run forever, accepting connections and handling requests. | 
| cannam@133 | 405   kj::NEVER_DONE.wait(waitScope); | 
| cannam@133 | 406 } | 
| cannam@133 | 407 {% endhighlight %} | 
| cannam@133 | 408 | 
| cannam@133 | 409 Note that for the bind address, Cap'n Proto supports DNS host names as well as IPv4 and IPv6 | 
| cannam@133 | 410 addresses.  The special address `*` can be used to bind to the same port on all local IPv4 and | 
| cannam@133 | 411 IPv6 interfaces.  Additionally, a Unix domain socket can be specified as `unix:` followed by a | 
| cannam@133 | 412 path name. | 
| cannam@133 | 413 | 
| cannam@133 | 414 For a more complete example, see the | 
| cannam@133 | 415 [calculator server sample](https://github.com/sandstorm-io/capnproto/tree/master/c++/samples/calculator-server.c++). | 
| cannam@133 | 416 | 
| cannam@133 | 417 ## Debugging | 
| cannam@133 | 418 | 
| cannam@133 | 419 If you've written a server and you want to connect to it to issue some calls for debugging, perhaps | 
| cannam@133 | 420 interactively, the easiest way to do it is to use [pycapnp](http://jparyani.github.io/pycapnp/). | 
| cannam@133 | 421 We have decided not to add RPC functionality to the `capnp` command-line tool because pycapnp is | 
| cannam@133 | 422 better than anything we might provide. |