Cap'n Protoo 배우기(3)

8866 단어 capnpidltech

샘플 코드:calculator


https://github.com/capnproto/capnproto/tree/master/c%2B%2B/samples
샘플 코드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 클라이언트를 설정하는 데 사용되는 초간단 인터페이스"라고 적혀 있습니다.다만, 일부 제한이 있는 것 같다.
  • 공공 단식 기능의 작은 구성 요소만 내보냅니다.이는 연결 간에 상태를 유지할 필요가 없는 임시 서비스에는 문제가 없지만 장기적인 리소스에 대해서는 Cap'n Protoo의 전력이 숨겨집니다.
  • EzRpcClient/EzRpcServer 자동 설정kj::EventLoop으로 스레드를 현재 상태로 만듭니다.각 스레드에는 kj::EventLoop만 존재할 수 있기 때문에 독특한 활동 구간을 설정하려면 이 인터페이스를 사용할 수 없습니다.(단, 한 라인에서 여러 개의 EzRpcClient/EzRpcServer 대상을 안전하게 만들 수 있습니다. 이것들은 한 개 이상의 활동 막대를 만들 수 없습니다.)
  • 이러한 클래스는 단순한 2자 간 연결만 지원하며 다중 룸 VatNetworks는 지원하지 않습니다.
  • 이런 종류는 암호화되지 않은 원시 플러그인의 통신만 지원한다.암호화 흐름을 지원하려면 저급 인터페이스를 사용하십시오.
  • capnp::EzRpcClient client(argv[1]); 다음과 같이 첫 번째 매개 변수에 서버 주소를 사용합니다.
     EzRpcClient(const struct sockaddr* serverAddress, uint addrSize,
                  ReaderOptions readerOpts = ReaderOptions());
    
    주소는 kj/async-io.hkj::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 통신용 훅이 전달된 것으로 이해할 수 있다.

    좋은 웹페이지 즐겨찾기