У нас есть шесть WSDL, скомпилированных в рамках одного проекта, и из-за некоторых аппаратных ограничений мы можем открыть только один порт для прослушивания.
Для этого мы выбираем подход, описанный в главе 7.2.8 Как объединить серверные классы C++ в цепочку для приема сообщений на одном и том же порту в этом Руководство по gSOAP.
Однако при использовании этого подхода мы сталкиваемся со многими серьезными проблемами:
<сильный>1. Если одновременно поступает много запросов, то иногда soap_begin_serve сообщает об ошибке с error=-1, сокет сразу же закрывается мыльным сервером после его установки
<сильный>2. Если мы вызовем xxx.destory() после soap_free_stream(), тогда soap_accept() сообщит об ошибке неверного файлового дескриптора и больше не будет работать (решено)
Кто-нибудь знает, каковы причины вышеуказанного явления? Как их решить?
Наш код очень близок к примеру, за исключением нескольких изменений, см. раздел ниже.
//server thread
Abc::soapABCService server; // generated with soapcpp2 -i -x -n -QAbc
server.bind(NULL, 12345, 100);
server.soap_mode = SOAP_KEEP_ALIVE | SOAP_UTF_CSTRING;
server.recv_timeout = server.send_timeout = 60;
while (true)
{
server.accept();
...
pthread_create(&pid, NULL, handle_new_request, server.copy());
} // while(true)
// work thread - the thread function
void *handle_new_request(void* arg)
{
// generated with soapcpp2 -i -x -n -QAbc
Abc::soapABCService *abc = (Abc::soapABCService*)arg;
Uvw::soapUVWService uvw; // generated with soapcpp2 -i -x -n -QUvw
Xyz::soapXYZService xyz; // generated with soapcpp2 -i -x -n -QXyz
if(soap_begin_serve(abc))
{
//sometimes it reports error
//due to unkown reason, socket was closed by soap server
abc->soap_stream_fault(std::cerr);
}
else if (abc->dispatch() == SOAP_NO_METHOD)
{
soap_copy_stream(&uvw, abc);
uww.state = SOAP_COPY;
if (uvw.dispatch() == SOAP_NO_METHOD)
{
soap_copy_stream(&xyz, &uvw);
xyz.state = SOAP_COPY;
if (xyz.dispatch())
{
soap_send_fault(&xyz); // send fault to client
xyz.soap_stream_fault(std::cerr);
}
soap_free_stream(&xyz); // free the copy
xyz.destroy();
}
else
{
soap_send_fault(&uvw); // send fault to client
uvw.soap_stream_fault(std::cerr);
}
soap_free_stream(&uvw); // free the copy
uvw.destroy();
}
else if (abc->error)
{
abc->soap_stream_fault(std::cerr);
}
else
{
}
abc->destroy();
delete abc;
abc = NULL;
}
soap_copy_stream
отuvw
доxyz
, хотя потокxyz
уже был освобожден. Можно лиsoap_copy_stream
использовать службу, которая уже былаsoap_free_stream
удалена? - person ssemilla   schedule 18.07.2015