Я новичок в Apache Thrift. Я хотел использовать его, чтобы помочь мне реализовать сервер, который принимает входные данные от клиента, анализирует их и, основываясь на этом, направляет их в соответствующую функцию, которая, в свою очередь, возвращает ответ на этот конкретный запрос.
Например:
Теперь я определил структуры, необходимые в mylist.thrift:
struct TGetListRequest {
1: i32_t id,
}
struct TGetListResponse {
1: string response_code, //FAIL or SUCCESS
2: list<string> nodes,
}
service TmyListService {
TGetListResponse getListReq( 1:TGetListRequest arg ),
}
Теперь это генерирует необходимые файлы:
TmyListService_server.skeleton.cpp
TmyListService.cpp
TmyListService.h
mylistconstants.cpp
mylistconstants.h
mylisttypes.cpp
mylisttypes.h
Содержимое первого файла копируется в TmyListService_server.cpp, где класс реализован с помощью его метода: getListReq следующим образом:
class TGetListRequestHandler: public TGetListRequestIf {
public:
TGetListResponse getListReq(TGetListRequest arg){
...
}
};
Я предоставил в нем следующий код для запуска сервера в функции main ():
int main(int argc, char **argv) {
int port = 9090;
shared_ptr<TmyListServiceHandler> handler(new TmyListServiceHandler());
shared_ptr<TProcessor> processor(new TmyListServiceProcessor(handler));
shared_ptr<TServerTransport> serverTransport(new TServerSocket(port));
shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFactory());
shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());
TSimpleServer server(processor, serverTransport, transportFactory, protocolFactory);
server.serve();
return 0;
}
Теперь самое сложное для меня:
Где я могу реализовать разбор входных данных от клиента к серверу? Мне сказали, что это простая реализация с использованием Thrift без необходимости писать свой парсер или использовать генератор парсера? Я не могу понять это? Где я говорю своему серверу, что делать с вводом, т.е. на какую функцию Req направлять его?
С точки зрения реализации клиента, у меня есть следующее:
int main(int argc, char **argv) {
boost::shared_ptr<TSocket> socket(new TSocket("localhost", 9090));
boost::shared_ptr<TTransport> transport(new TBufferedTransport(socket));
boost::shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport));
TmyListServiceClient client(protocol);
TGetListRequest arg;
arg.id = 1;
TGetListResponse argz;
transport->open();
client.send_getListReq( arg );
printf("DONE SEDNING");
client.recv_getListReq( argz );
transport->close();
return 0;
}
Это в основном не делает ничего, кроме открытия клиентского соединения. Он не принимает никакого ввода вообще. Я уверен, что это также связано с реализацией логики обработки в первую очередь на сервере, но что я должен делать здесь, чтобы клиент был готов к тестированию на сервере?
Вы почти закончили!
На вашем сервере вы показываете этот код:
shared_ptr<TProcessor> processor(new TmyListServiceProcessor(handler));
Где обработчик ?! Это класс, который реализует ваш сервис.
Что-то вроде:
class TmyListServiceHandler: public TmyListServiceIf {
public:
virtual TGetListResponse getListReq(TGetListRequest arg) override {
}
};
База для вашего сервиса (TmyListServiceIf) создается в: TmyListService.h
>
Глядя на изменения, внесенные вами в вопрос, я думаю, что у вас все еще есть
проблема обработчика. Класс Handler объявлен: TGetListRequestHandler
в новом коде вы добавили.
Тем не менее, вы создаете TmyListServiceHandler в основной функции
сервер. Я видел, как это происходит, когда люди меняют вещи в IDL
и восстановить код, не удаляя старый вывод. Вы в конечном итоге с двумя
разные определения вещей. Вы должны использовать TmyListServiceHandler
везде.
Согласно вашему IDL, TGetListRequest является структурой и не должен иметь обработчик.
Других решений пока нет …