gpt4 book ai didi

c++ - 使用 gSoap 链接多个 SOAP 服务时启用保持事件

转载 作者:太空宇宙 更新时间:2023-11-04 12:44:45 24 4
gpt4 key购买 nike

我们有一个执行 soap 方法代理的 C++ Windows 项目。我们使用 gSoap 来实现输入/服务器服务以通过 SOAP 方法接受数据,并使用输出/客户端服务来代理对远程系统的传入调用。

SOAP 服务是在固定的遗留规范中定义的,我们无法控制我们从中接收数据的客户端系统或我们将数据代理到的服务器。

SOAP 服务在多个 WSDL 规范中定义,我们的系统必须在一个服务器端口/端点后实现所有服务。 gSoap 文档涵盖了此要求(第 How to Chain C++ Server Classes to Accept Messages on the Same Port 部分)并且我们的代码严格遵循该指南。

总的来说,系统运行良好,我们有一个独立部署的集成轻量级解决方案。

但是代码部署在一些密集的高容量/高调用频率的情况下,这给我们带来了几个问题。我相信如果服务器端服务允许 HTTP keep-alive,我们的问题就会得到解决,但是用于链接多个服务的记录的 gSoap 方法特别建议不要启用 HTTP keep-alive:

Do not enable keep-alive support, as the socket may stay open indefinitely afterwards as a consequence.

我们多次尝试通过使用 SOAP_IO_KEEPALIVE 标志启动服务/gSoap 来忽略此建议,但 gSoap HTTP 连接处理中似乎有代码强制在每个 SOAP 事务完成后关闭连接。

这些是此限制导致的问题类型:

  • 普遍担心在大批量情况下需要为每个唯一事务建立新的 HTTP 连接会导致效率低下。对短暂的端口耗尽的担忧。
  • 一些客户端尝试使用 HTTP Expect: 100-continue 调用带有部分数据负载的 SOAP 方法。这些事务总是失败,因为连接被 gSoap 服务器关闭,使客户端没有机会继续。
  • 有时需要使用安全的 SSL 通信。但是,如果没有 HTTP keep-alive,客户端需要为每个事务协商一个 SSL 连接,这在高调用频率的情况下会带来高得令人望而却步的开销。

关于我们实现的一些细节:我们使用 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 系统的记录限制,但在我看来其他人可能遇到过类似的问题。有没有人找到可以分享的解决方案/解决方法?

最佳答案

我在这里分享我自己的问题的答案。我最终得到了 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 支持的回复:

The approach is fine to make sure HTTP keep-alive is enabled while running the server loop.

The example in the documentation is a simplified approach to show the logic of chaining multiple attempted dispatches, but it has the keep-alive limitation you stated.

But that does not prevent the use of the same strategy we use for a non-changed service dispatching. The code you are using is fine, replacing the gist of the loop body by the dispatch attempts.

Wondering if we should say something in the documentation about this limitation, since it does not mention this.

关于c++ - 使用 gSoap 链接多个 SOAP 服务时启用保持事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52277982/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com