我们有一个执行肥皂方法代理的C ++ Windows项目。我们使用gSoap实现输入/服务器服务以通过SOAP方法接受数据,并使用输出/客户端服务将传入的呼叫代理到远程系统。
SOAP服务是在固定的遗留规范中定义的,我们无法控制从中接收数据的客户端系统或将数据代理到的服务器。
SOAP服务在多个WSDL规范中定义,并且我们的系统必须在一个服务器端口/端点之后实现所有服务。 gSoap文档满足了这一要求(第How to Chain C++ Server Classes to Accept Messages on the Same Port节),我们的代码严格遵循该指南。
总体上,该系统运行良好,并且我们有一个独立部署的集成轻型解决方案。
但是代码被部署在一些密集的高流量/高呼叫频率的情况下,这给我们带来了一些问题。我相信,如果服务器端服务允许HTTP保持活动状态,我们的问题将得到解决,但是已记录的用于链接多个服务的gSoap方法特别建议不要启用HTTP保持活动状态:
请勿启用保持活动状态支持,因为套接字可能保持打开状态 结果无限期地结束。
我们已经尝试通过使用SOAP_IO_KEEPALIVE标志启动services / gSoap来忽略该建议,但是gSoap HTTP连接处理中似乎存在代码,迫使每个SOAP事务完成后关闭连接。
这些是此限制导致的问题类型:
有关我们实施的一些详细信息: 我们使用gSoap WSDL2H组合服务:
wsdl2h -NServTest -s -o ServTestWebServices.h Service1.wsdl Service2.wsdl Service3.wsdl
生成的gSoap定义然后用于实现服务器端服务类:
soapcpp2 -S -j -w -qServTestWSIn -x ServTestWebServices.h
通常在实现gSoap集成HTTP连接处理而没有服务链时,代码仅接受连接并调用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系统的文件限制,但是在我看来,其他人可能也遇到过类似的问题。有没有人找到可以共享的解决方案/解决方法?
答案 0 :(得分:0)
我在这里分享我自己的问题的答案。最终,我从gSoap员工那里得到了一些帮助,他们确认我找到的解决方案应该没有问题。这是我现在正在使用的代码的要点(基于问题中的代码):
gsoap->keep_alive = gsoap->max_keep_alive + 1;
do
{
if ((gsoap->keep_alive > 0) && (gsoap->max_keep_alive > 0))
gsoap->keep_alive--;
if (soap_begin_serve(gsoap))
{
if (gsoap->error >= SOAP_STOP)
continue;
else
break;
}
if ((SoapServeResult = srv1.dispatch()) == SOAP_NO_METHOD)
if ((SoapServeResult = srv2.dispatch()) == SOAP_NO_METHOD)
if ((SoapServeResult = srv3.dispatch()) == SOAP_NO_METHOD)
{
//no method found - send fault to client
soap_send_fault(srv3.soap);
}
} while (m_pSoap->keep_alive);
这是Genivia / gSoap支持的回复:
该方法可以确保在启用HTTP保持活动的同时 运行服务器循环。
文档中的示例是一种简化的方法,用于显示 链接多个尝试调度的逻辑,但是它具有 您所说的保持活动限制。
但这不会阻止我们使用与 不变的服务调度。您使用的代码很好, 用调度尝试替换循环主体的要点。
想知道我们是否应该在文档中对此说些什么 限制,因为它没有提及。