【发布时间】:2014-08-11 17:14:20
【问题描述】:
我对 CORBA 异步调用 (AMI) 有一个问题。问题是客户端的回调永远不会被调用。
我简化了 ACE_Wrappers\TAO\examples\Content_Server\AMI_Observer 中的示例。 IDL:
module MyServer
{
interface Callback
{
void next_chunk (in string chunk, in boolean last_chunk);
};
interface ContentFactory
{
string register_callback (in string message, in Callback client_callback);
};
};
在我的代码中,AMI 调用仅适用于 ContentFactory。代码是:
//Client.cpp:
CORBA::ORB_var orb = CORBA::ORB_init (argc,argv, "Mighty ORB");
CORBA::Object_var obj1 = orb->string_to_object (argv[1]);
MyServer::ContentFactory_var factory = MyServer::ContentFactory::_narrow(obj1);
if (CORBA::is_nil (factory.in ())) { }
// Get the Root POA.
CORBA::Object_var obj = orb->resolve_initial_references ("RootPOA");
PortableServer::POA_var poa =PortableServer::POA::_narrow (obj.in ());
// Activate the POA manager.
PortableServer::POAManager_var mgr = poa->the_POAManager ();
mgr->activate ();
// Variable used to keep track of when file retrieval has
// completed.
int request_count = 0;
// Activate and run the reply handlers.
//invoke_request(&request_count, factory.in());
////////////////////
MyServer_AMI_ContentFactoryHandler_i handler_i (&request_count);
MyServer::AMI_ContentFactoryHandler_var handler = handler_i._this ();
MyServer_Callback_i* callback_servant_ = new MyServer_Callback_i ();
// Pass ownership of the Callback servant to the POA.
PortableServer::ServantBase_var tmp (callback_servant_);
// Activate the Callback.
MyServer::Callback_ptr callback_ = callback_servant_->_this ();
factory->sendc_register_callback(handler.in(), "xushijie", callback_);
///////////////
// 1 millisecond delay to reduce "busy waiting" in ORB event
// loop.
ACE_Time_Value tv (0, 1000);
// Run the ORB event loop.
while (request_count > 0)
{
if (orb->work_pending ())
{
orb->perform_work ();
}
else
ACE_OS::sleep (tv);
}
orb->shutdown (0);
//serverI.h
class MyServer_AMI_ContentFactoryHandler_i
: public virtual POA_MyServer::AMI_ContentFactoryHandler
{
public:
// Constructor
MyServer_AMI_ContentFactoryHandler_i (int* requestCount);
// Destructor
virtual ~MyServer_AMI_ContentFactoryHandler_i (void);
virtual
void register_callback (
const char * ami_return_val);
virtual
void register_callback_excep (
::Messaging::ExceptionHolder * excep_holder);
public:
int* _request_count;
private:
void deactivated(void);
};
//serverI.cpp:
MyServer_AMI_ContentFactoryHandler_i::MyServer_AMI_ContentFactoryHandler_i (int* request_count)
{
_request_count = request_count;
(*this->_request_count)++;
std::cout<<" BUild AMI Content Factory Handle and request count: "<<(*this->_request_count)<<std::endl;
}
// Implementation skeleton destructor
MyServer_AMI_ContentFactoryHandler_i::~MyServer_AMI_ContentFactoryHandler_i (void)
{
}
void MyServer_AMI_ContentFactoryHandler_i::register_callback (
const char * ami_return_val)
{
(*this->_request_count)--;
std::cout<<" Reply from contentServer: "<<ami_return_val<<" "<<(*this->_request_count)<<std::endl;
this->deactivated();
}
指针 request_count 被传递给 MyServer_AMI_ContentFactoryHandler_i 构造,其指向的值增加。一旦调用了 AMI 回调 register_callback,指向的 request_count 值就会减小,这反过来又会完成 main 函数中的 while 循环。
servant 端的 register_callback 只休眠 5 秒,然后返回一个 hello 字符串。此代码编译正常,但从未调用 MyServer_AMI_ContentFactoryHandler_i::register_callback。在调试过程中,orb->work_pending()一直返回false..
我还将我的代码与 AMI_Observer 和页面上的原始示例进行了比较:http://www.dre.vanderbilt.edu/~schmidt/DOC_ROOT/TAO/docs/tutorials/Quoter/AMI/index.html。这个问题花了我一天的时间,我迷路了..
谢谢你能帮忙指出我的错误...
/////////////////////////////////////// //////////////////////p>
更新:
调试级别为 10 的日志:
TAO_Messaging (9056|2720) - Asynch_Invocation_Adapter::invoke
TAO (9056|2720) - Invocation_Adapter::invoke_i, making a TAO_CS_REMOTE_STRATEGY invocation
TAO (9056|2720) - Transport_Cache_Manager_T::fill_set_i, current_size = 0, cache_maximum = 512
TAO (9056|2720) - Transport_Cache_Manager_T::purge, Cache size after purging is [0]
TAO (9056|2720) - IIOP_Connector::begin_connection, to <192.168.1.143:13638> which should block
TAO (9056|2720) - TAO_LF_CH_Event[0]::state_changed_i, state LFS_IDLE->LFS_CONNECTION_WAIT
TAO (9056|2720) - IIOP_Connection_Handler[8353360]::IIOP_Connection_Handler, this=007F0370
TAO (9056|2720) - IIOP_Connection_Handler::open, The local addr is <192.168.1.143:13674>
TAO (9056|2720) - IIOP_Connection_Handler::open, IIOP connection to peer <192.168.1.143:13638> on 528
TAO (9056|2720) - Transport::post_open, tport id changed from 8353360 to 528
TAO (9056|2720) - Transport[528]::post_open, cache_map_entry_ is 0
TAO (9056|2720) - TAO_LF_CH_Event[528]::state_changed_i, state LFS_CONNECTION_WAIT->LFS_SUCCESS
TAO (9056|2720) - Cache_IntId_T::Cache_IntId_T, this=0034E670 Transport[528] is connected
TAO (9056|2720) - Cache_IntId_T::recycle_state, ENTRY_UNKNOWN->ENTRY_IDLE_AND_PURGABLE Transport[528] IntId=0034E670
TAO (9056|2720) - Transport_Cache_Manager_T::bind_i, Transport[528] @ hash:index{-1062717739:0}
TAO (9056|2720) - Transport_Cache_Manager_T::bind_i: Success Transport[528] @ hash:index{-1062717739:0}. Cache size is [1]
TAO (9056|2720) - IIOP_Connector::make_connection, new connected connection to <192.168.1.143:13638> on Transport[528]
TAO (9056|2720) - Transport[528]::register_handler
TAO (9056|2720) - Transport[528]::register_handler - registering event handler with reactor
TAO (9056|2720) - Transport_Connector::connect, opening Transport[528] in TAO_CLIENT_ROLE
TAO (9056|2720) - Transport_Cache_Manager_T::is_entry_available_i[528], true, state is ENTRY_IDLE_AND_PURGABLE
TAO (9056|2720) - Cache_IntId_T::recycle_state, ENTRY_IDLE_AND_PURGABLE->ENTRY_BUSY Transport[528] IntId=007B588C
TAO (9056|2720) - Transport_Cache_Manager_T::find_i, Found available Transport[528] @hash:index {-1062717739:0}
TAO (9056|2720) - Transport_Connector::connect, got an existing connected Transport[528] in role TAO_CLIENT_ROLE
TAO (9056|2720) - Codeset_Manager_i::set_tcs, setting char translator (00010001)
TAO (9056|2720) - Codeset_Manager_i::set_tcs, setting wchar translator (00010109)
TAO (9056|2720) - Muxed_TMS[528]::request_id, <1>
**//BEGIN DEVELIER DATA**
TAO (9056|2720) - Codeset_Manager_i::generate_service_context, using tcs_c <ISO8859_1> (00010001), tcs_w <UTF-16> (00010109)
TAO (9056|2720) - GIOP_Message_Base::dump_msg, send GIOP message v1.2, 260 data bytes, my endian, Type Request[1]
GIOP message - HEXDUMP 272 bytes
47 49 4f 50 01 02 01 00 04 01 00 00 01 00 00 00 GIOP............
03 00 00 00 00 00 cd cd 1b 00 00 00 14 01 0f 00 ................
52 53 54 54 0c e9 53 bb 33 0a 00 00 00 00 00 01 RSTT..S.3.......
00 00 00 01 00 00 00 cd 12 00 00 00 72 65 67 69 ............regi
73 74 65 72 5f 63 61 6c 6c 62 61 63 6b 00 cd cd ster_callback...
01 00 00 00 01 00 00 00 0c 00 00 00 01 cd cd cd ................
01 00 01 00 09 01 01 00 09 00 00 00 78 75 73 68 ............xush
69 6a 69 65 00 cd cd cd 1a 00 00 00 49 44 4c 3a ijie........IDL:
4d 79 53 65 72 76 65 72 2f 43 61 6c 6c 62 61 63 MyServer/Callbac
6b 3a 31 2e 30 00 cd cd 01 00 00 00 00 00 00 00 k:1.0...........
6c 00 00 00 01 01 02 cd 0e 00 00 00 31 39 32 2e l...........192.
31 36 38 2e 31 2e 31 34 33 00 69 35 1b 00 00 00 168.1.143.i5....
14 01 0f 00 52 53 54 c4 0c e9 53 61 3d 08 00 01 ....RST...Sa=...
00 00 00 01 00 00 00 02 00 00 00 cd 02 00 00 00 ................
00 00 00 00 08 00 00 00 01 cd cd cd 00 4f 41 54 .............OAT
01 00 00 00 18 00 00 00 01 cd cd cd 01 00 01 00 ................
01 00 00 00 01 00 01 05 09 01 01 00 00 00 00 00 ................
TAO (9056|2720) - Transport[528]::send_asynchronous_message_i, trying to send the message (ml = 272)
TAO (9056|2720) - Transport[528]::drain_queue_helper, sending 1 buffers
TAO (9056|2720) - Transport[528]::drain_queue_helper, buffer 0/1 has 272 bytes
TAO - Transport[528]::drain_queue_helper (0/272) - HEXDUMP 272 bytes
47 49 4f 50 01 02 01 00 04 01 00 00 01 00 00 00 GIOP............
03 00 00 00 00 00 cd cd 1b 00 00 00 14 01 0f 00 ................
52 53 54 54 0c e9 53 bb 33 0a 00 00 00 00 00 01 RSTT..S.3.......
00 00 00 01 00 00 00 cd 12 00 00 00 72 65 67 69 ............regi
73 74 65 72 5f 63 61 6c 6c 62 61 63 6b 00 cd cd ster_callback...
01 00 00 00 01 00 00 00 0c 00 00 00 01 cd cd cd ................
01 00 01 00 09 01 01 00 09 00 00 00 78 75 73 68 ............xush
69 6a 69 65 00 cd cd cd 1a 00 00 00 49 44 4c 3a ijie........IDL:
4d 79 53 65 72 76 65 72 2f 43 61 6c 6c 62 61 63 MyServer/Callbac
6b 3a 31 2e 30 00 cd cd 01 00 00 00 00 00 00 00 k:1.0...........
6c 00 00 00 01 01 02 cd 0e 00 00 00 31 39 32 2e l...........192.
31 36 38 2e 31 2e 31 34 33 00 69 35 1b 00 00 00 168.1.143.i5....
14 01 0f 00 52 53 54 c4 0c e9 53 61 3d 08 00 01 ....RST...Sa=...
00 00 00 01 00 00 00 02 00 00 00 cd 02 00 00 00 ................
00 00 00 00 08 00 00 00 01 cd cd cd 00 4f 41 54 .............OAT
01 00 00 00 18 00 00 00 01 cd cd cd 01 00 01 00 ................
01 00 00 00 01 00 01 05 09 01 01 00 00 00 00 00 ................
TAO (9056|2720) - Transport[528]::drain_queue_helper, end of data
TAO (9056|2720) - Transport[528]::cleanup_queue, byte_count = 272
TAO (9056|2720) - Transport[528]::cleanup_queue, after transfer, bc = 0, all_sent = 1, ml = 0
TAO (9056|2720) - Transport[528]::drain_queue_helper, byte_count = 272, head_is_empty = 1
TAO (9056|2720) - Transport[528]::drain_queue_i, helper retval = 1
TAO (9056|2720) - Transport[528]::make_idle
**//The data in buffer is sent then idle.......**
TAO (9056|2720) - Cache_IntId_T::recycle_state, ENTRY_BUSY->ENTRY_IDLE_AND_PURGABLE Transport[528] IntId=007B588C
我对TAO日志不是很熟悉,但是根据上面的日志,似乎服务器没有响应..
////////////////////////////////// 更新: 现在找出根本原因.. 仆人
char * MyServer_ContentFactory_i::register_callback (const char * message, ::MyServer::Callback_ptr client_callback)
{
ACE_OS::sleep(5);
if (CORBA::is_nil (client_callback)) // @@ Will it ever be nil?
throw CORBA::BAD_PARAM ();
..........
return "xushijie"; // >__< errors..
}
将return语句改为:
CORBA::String_var str = CORBA::string_dup("xushijie");
return str._retn();
这个例子现在可以工作了..
【问题讨论】:
-
使用 -ORBDebugLevel 10 运行您的应用程序,看看 ORB 告诉我们什么。您是否还检查了以下示例dre.vanderbilt.edu/~schmidt/DOC_ROOT/TAO/tests/AMI。此外,您似乎有此工作,因为您提出的问题确实表明 AMI 工作 (stackoverflow.com/questions/19917665/…)
-
谢谢@JohnnyWillemsen。我确实有另一个成功的例子。我的根本原因是在服务端,其中一个常量字符串是响应(见上面的帖子)。这会导致 ORB 麻烦,尽管不清楚什么是麻烦。并且客户端没有收到任何响应..
-
当客户端传递一个 nil 引用时,client_callback 可能为 nil,没有什么可以阻止它这样做。
标签: asynchronous corba tao ace-tao