Cap'n Protoo 배우기(3)
샘플 코드:calculator
샘플 코드calculator입니다.
calculator-client.c++
capnp::EzRpcClient client(argv[1]);
Calculator::Client calculator = client.getMain<Calculator>();
처음부터 확실하지는 않았지만 서버 주소를 통해 클라이언트 등급을 구축하여 이번에 처리된calculator 전용 클라이언트 등급을 만들었다.아마도 EzRpcClient는 통신 클래스일 것입니다. Calculator::클라이언트는 데이터의 직렬화를 위한 클래스입니까?약간의 위화감은 있지만 C#도 HttpClient에서 통신을 덮어쓴 것을 감안하면 데이터의 엄숙화는 Json의 프로그램 라이브러리를 사용했기 때문에 비슷할 수 있다.
EzRpcClient
EzRpc~를 사용하여 통신하는 코드인 것 같습니다.
EzRpcClient 메시지 헤더에 "Cap'n Protoo RPC 클라이언트를 설정하는 데 사용되는 초간단 인터페이스"라고 적혀 있습니다.다만, 일부 제한이 있는 것 같다.kj::EventLoop으로 스레드를 현재 상태로 만듭니다.각 스레드에는 kj::EventLoop만 존재할 수 있기 때문에 독특한 활동 구간을 설정하려면 이 인터페이스를 사용할 수 없습니다.(단, 한 라인에서 여러 개의 EzRpcClient/EzRpcServer 대상을 안전하게 만들 수 있습니다. 이것들은 한 개 이상의 활동 막대를 만들 수 없습니다.) capnp::EzRpcClient client(argv[1]); 다음과 같이 첫 번째 매개 변수에 서버 주소를 사용합니다. EzRpcClient(const struct sockaddr* serverAddress, uint addrSize,
ReaderOptions readerOpts = ReaderOptions());
주소는 kj/async-io.h의kj::Network에 따라 분석되었기 때문에 학급 구조기를 보면 IPv4, IPv6, Unix domain socket을 사용할 수 있을 것 같다.문자열의 해석률은 다음 함수를 통해 진행되는 것 같습니다. static Promise<Array<SocketAddress>> parse(
LowLevelAsyncIoProvider& lowLevel, StringPtr str, uint portHint, _::NetworkFilter& filter) {
// TODO(someday): Allow commas in `str`.
SocketAddress result;
if (str.startsWith("unix:")) {
StringPtr path = str.slice(strlen("unix:"));
KJ_REQUIRE(path.size() < sizeof(addr.unixDomain.sun_path),
"Unix domain socket address is too long.", str);
KJ_REQUIRE(path.size() == strlen(path.cStr()),
"Unix domain socket address contains NULL. Use"
" 'unix-abstract:' for the abstract namespace.");
result.addr.unixDomain.sun_family = AF_UNIX;
strcpy(result.addr.unixDomain.sun_path, path.cStr());
以下、長いので省略
Calculator::Client
Calculator::Client calculator = client.getMain<Calculator>();에서 Calculator를 템플릿 매개 변수로 추출합니다. Calculator: Client.getMain이 뭐예요?
template <typename Type>
inline typename Type::Client EzRpcClient::getMain() {
return getMain().castAs<Type>();
}
getMain의 반환값은cast입니다.Capability::Client EzRpcClient::getMain() {
KJ_IF_MAYBE(client, impl->clientContext) {
return client->get()->getMain();
} else {
return impl->setupPromise.addBranch().then([this]() {
return KJ_ASSERT_NONNULL(impl->clientContext)->getMain();
});
}
}
KJ_IF_MAYBE메이비 모나드인 것 같아요.Maybe monado는 대략적으로 std:optional 같은 것이고null lptr나 T형의 값이 있는 것이다.KJ_IF_MAYBE(client, impl->clientContext)에서nullpttr는 client를 대입impl->clientContext하는 동시에 판정한다.나는 이런 작법이 매우 멋있다고 생각한다.clientContextkj::AsyncIoStreamgetMain()에서 얻을 수 있다Capability::Client.응.전혀 몰라요.
capnp의 Capability를 보면 다음과 같은 평어가 있습니다.
// A capability without type-safe methods. Typed capability clients wrap `Client` and typed
// capability servers subclass `Server` to dispatch to the regular, typed methods.
유형이 안전한 방법이 없는capability.타입의capability 클라이언트Client는 랩으로 싸여 있고, 타입의capability 서버는 Server를 하위 클래스로 하여 일반적인 타입 방법으로 분배한다.capability는 기능과 용량을 나타내는 뜻이기 때문에 저는 Calculator라는 구체적인 기능(capability)을 가진 센터를 만드는 것을 잠시 이해했습니다.
여기서
return getMain().castAs<Type>();뒷부분을보면...template <typename T>
inline typename T::Client Capability::Client::castAs() {
return typename T::Client(hook->addRef());
}
훅의 참조 계수를 늘리면서 Calculator::Client에 건네준다.hook은 Piperline Hook입니다.이렇게 하면
Calculator::Client 통신용 훅이 전달된 것으로 이해할 수 있다.
Reference
이 문제에 관하여(Cap'n Protoo 배우기(3)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://zenn.dev/yae/articles/e39281bd083afa텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)