Apache Thrift для простой обработки, а не для сервера - PullRequest
0 голосов
/ 17 июня 2019

Надеюсь, я не неправильно понял концепцию Thrift, но из (примера) вопросов, подобных этому , эта структура состоит из различных модульных слоев, которые можно включать или отключать.

В основном я заинтересован в «части IDL» Thrift, так что я могу создать общий интерфейс между моим кодом C ++ и внешним приложением Javascript. Я хотел бы вызывать функции C ++, используя JS, с передачей двоичных данных, и я уже использовал для этого компилятор.

Но и мое C ++ (сервер), и JS (клиентское) приложение уже обмениваются данными с помощью веб-сервера C ++ с поддержкой Websockets, это не предоставляется Thrift .

Итак, я подумал настроить следующие элементы:

  • В JS (уже сделано):

    • TWebSocketTransport для отправки данных на мой «сервер веб-сокетов» (с хостом ws: //xxx.xxx.xxx.xxx)
    • TBinaryProtocol для инкапсуляции данных (используя эту реализацию JS )
    • Скомпилированная библиотека Thrift JS с соответствующими функциями C ++ для вызова (выполняется с помощью JS-компилятора)
  • В C ++ (частично):

    • TBinaryProtocol для кодирования / декодирования данных
    • TP-процессор с обработчиком для получения данных от клиента и их обработки

На данный момент клиент уже может отправлять запросы на мой сервер веб-сокетов, я вижу их получение в двоичном виде, и мне просто нужно Thrift для:

  1. Декодировать ввод
  2. Вызвать соответствующую функцию C ++
  3. Кодировать вывод

Мой веб-сервер отправит ответ клиенту. Таким образом, здесь не нужен «Комиссионный сервер». Я вижу, что есть функция TProcessor-> process (), я пытаюсь использовать ее, когда получаю двоичные данные, но для этого нужен вход / выход TProtocol. Здесь нет проблем ... но для создания TBinaryProtocol мне также нужен TTransport! Если не ожидается Thrift-сервер ... какой транспорт я должен использовать?

Я пытался установить TTransport в NULL в конструкторе TBinaryProtocol, но как только я его использую, он выдает исключение nullptr.

Код выглядит примерно так:

Init:

boost::shared_ptr<MySDKServiceHandler> handler(new MySDKServiceHandler());
thriftCommandProcessor = boost::shared_ptr<TProcessor>(new MySDKServiceProcessor(handler));

thriftInputProtocol = boost::shared_ptr<TBinaryProtocol>(new TBinaryProtocol(TTransport???));
thriftOutputProtocol = boost::shared_ptr<TBinaryProtocol>(new TBinaryProtocol(TTransport???));

Когда поступают данные:

this->thriftInputProtocol->writeBinary(input); // exception here
this->thriftCommandProcessor->process(this->thriftInputProtocol, this->thriftOutputProtocol, NULL);
this->thriftOutputProtocol->readBinary(output);

Ответы [ 2 ]

1 голос
/ 19 июня 2019

Мне удалось сделать это, используя следующие компоненты:

// create the Processor using my compiled Thrift class (from IDL)
boost::shared_ptr<MySDKServiceHandler> handler(new MySDKServiceHandler());
thriftCommandProcessor = boost::shared_ptr<TProcessor>(new ThriftSDKServiceProcessor(handler));

// Transport is needed, I use the TMemoryBuffer so everything is kept in local memory
boost::shared_ptr<TTransport> transport(new apache::thrift::transport::TMemoryBuffer());

// my client/server data is based on binary protocol. I pass the transport to it
thriftProtocol = boost::shared_ptr<TProtocol>(new TBinaryProtocol(transport, 0, 0, false, false));

/* .... when the message arrives through my webserver */
void parseMessage(const byte* input, const int input_size, byte*& output, int& output_size)
{
    // get the transports to write and read Thrift data
    boost::shared_ptr<TTransport> iTr = this->thriftProtocol->getInputTransport();
    boost::shared_ptr<TTransport> oTr = this->thriftProtocol->getOutputTransport();

    // "transmit" my data to Thrift
    iTr->write(input, input_size);
    iTr->flush();

    // make the Thrift work using the Processor
    this->thriftCommandProcessor->process(this->thriftProtocol, NULL);

    // the output transport (oTr) contains the called procedure result
    output = new byte[MAX_SDK_WS_REPLYSIZE];
    output_size = oTr->read(output, MAX_SDK_WS_REPLYSIZE);
}
1 голос
/ 17 июня 2019

Мой веб-сервер отправит ответ клиенту.Таким образом, здесь не нужен «Комиссионный сервер».Я вижу, что есть функция TProcessor-> process (), я пытаюсь использовать ее, когда получаю двоичные данные, но для этого нужен вход / выход TProtocol.Здесь нет проблем ... но для создания TBinaryProtocol мне также нужен TTransport!Если не ожидается Thrift-сервер ... какой транспорт я должен использовать?

Обычный шаблон - хранить где-то биты и использовать этот буфер или поток данных в качестве входных данных, то же самое для выходных данных.Для некоторых языков доступен TStreamTransport, для C ++ класс TBufferBase выглядит многообещающе.

...