У нас есть проект Windows C ++, который выполняет проксирование метода мыла. Мы используем gSoap для реализации как служб ввода / сервера для приема данных с помощью методов SOAP, так и служб вывода / клиента для передачи входящих вызовов в удаленную систему.
Сервисы SOAP определены в фиксированной устаревшей спецификации, и мы не можем контролировать клиентские системы, с которых мы получаем данные, или сервер, на который мы передаем данные.
Сервисы SOAP определены в нескольких спецификациях WSDL, и наша система должна реализовать все сервисы за одним портом / конечной точкой сервера. Документация gSoap покрывает это требование (раздел Как связать классы серверов C ++ для приема сообщений на одном и том же порту) и наш кодекс следует руководству
В целом система работает хорошо, и у нас есть интегрированное легкое решение, которое развернуто автономно.
Но код разворачивается в некоторых интенсивных ситуациях с большим объемом / высокой частотой вызовов, и это создает нам несколько проблем. Я полагаю, что наши проблемы были бы решены, если бы серверные сервисы позволяли поддерживать HTTP-поддержку, но документированный метод gSoap для объединения нескольких сервисов специально запрещает включение HTTP-поддержки:
Не включайте поддержку поддержки активности, так как сокет может оставаться открытым
неопределенно впоследствии как следствие.
Мы предприняли несколько попыток проигнорировать этот совет, инициировав services / gSoap с флагом SOAP_IO_KEEPALIVE, но в обработке HTTP-соединений gSoap, похоже, есть код, который вынуждает закрывать соединения после завершения каждой транзакции SOAP.
Вот типы проблем, которые вызывает это ограничение:
Некоторые подробности о нашей реализации:
Мы объединяем сервисы, используя gSoap WSDL2H:
wsdl2h -NServTest -s -o ServTestWebServices.h Service1.wsdl Service2.wsdl Service3.wsdl
Полученное определение gSoap затем используется для реализации классов обслуживания на стороне сервера:
soapcpp2 -S -j -w -qServTestWSIn -x ServTestWebServices.h
Обычно при реализации интегрированной обработки HTTP-соединений gSoap без сервисной цепочки код просто принимает соединения и вызывает soap_serve для обработки всего времени жизни соединения:
struct soap gsoap;
soap_init2(&gsoap, SOAP_IO_KEEPALIVE, SOAP_IO_KEEPALIVE);
SOAP_SOCKET m = soap_bind(gsoap, NULL, port, backlog);
while (soap_valid_socket(soap_accept(gsoap)))
{
soap_serve(gsoap);
soap_destroy(gsoap);
soap_end(gsoap);
}
При связывании нескольких сервисов soap_serve () не работает, так как он не способен направить вызов на правильный сервис. Вместо этого используется следующий подход:
struct soap gsoap;
//SOAP_IO_KEEPALIVE does not help here:
soap_init2(&gsoap, SOAP_IO_KEEPALIVE, SOAP_IO_KEEPALIVE);
Service1 srv1(gsoap);
Service2 srv2(gsoap);
Service3 srv3(gsoap);
SOAP_SOCKET m = soap_bind(gsoap, NULL, port, backlog);
while (soap_valid_socket(soap_accept(gsoap)))
{
if (soap_begin_serve(gsoap))
soap_stream_fault(gsoap, std::cerr);
else
{
if (srv1.dispatch() == SOAP_NO_METHOD)
if (srv2.dispatch() == SOAP_NO_METHOD)
srv3.dispatch();
if (soap->error)
soap_send_fault(gsoap);
}
}
Я понимаю, что это задокументированное ограничение системы gSoap, но мне кажется, что другие могут испытывать подобные проблемы. Кто-нибудь нашел решение / обходной путь, которым они могли бы поделиться?
Задача ещё не решена.
Других решений пока нет …