现在正用ActiveMQ C++客户端开发,发现有个问题,当开始连接ActiveMQ服务器成功后,成功发送数据后,此时ActiveMQ服务器停止,客户端无法退出,出现挂掉现象。
通过调试代码当客户端退出调用如下代码:
try{ if( producer != NULL ) delete producer; }catch ( CMSException& e ) { e.printStackTrace(); } producer = NULL; // Close open resources. try{ if( session != NULL ) session->close(); if( connection != NULL ) connection->close(); }catch ( CMSException& e ) { e.printStackTrace(); } try{ if( session != NULL ) delete session; }catch ( CMSException& e ) { e.printStackTrace(); } session = NULL; try{ if( connection != NULL ) delete connection; }catch ( CMSException& e ) { e.printStackTrace(); } connection = NULL;
程序报异常,检查代码发现在ActiveMQSession.cpp中,delete producer会调用close方法,然后调用ActiveMQSession::disposeOf方法,而里面会调用this->connection->disposeOf( id );这个过程会发送指令到服务器,在服务器关闭后会抛异常,而没有调用session的this->producers.remove( id ); 在producer的析构函数中,会将所有异常捕获不往外抛,此时proceducer对象被顺利删除,在session的producers中并没有将此producer移除掉,而在session关闭时,会调用ActiveMQSession::close() 方法,在此方法中将所有的producer关掉,而此时会调用到被删除的producer,所以报错。
同理session对connection也有这个情况,在ActiveMQSession::close()方法中,会同样调用this->connection->disposeOf( this->sessionInfo->getSessionId() );让connectio移除session.
所以需要修改代码,在ActiveMQSession.cpp中增加如下代码
#ifdef HHESOCKET_ERROR #define HHSOCKETERROR_START / try{ #define HHSOCKETERROR_END / } / catch(ActiveMQException& ex) { / const decaf::io::IOException* exception1 = dynamic_cast<const decaf::io::IOException*>(ex.getCause()); / if (NULL != exception1) { / string data = exception1->getMessage(); / if (NULL == strstr(data.c_str(), "decaf::net::SocketOutputStream::write")) / throw ex; / } / else / throw ex; / } #endif
修改ActiveMQSession::close()方法将this->connection->disposeOf( this->sessionInfo->getSessionId() );改为如下代码:
#ifdef HHESOCKET_ERROR HHSOCKETERROR_START #endif // Remove this session from the Broker. this->connection->disposeOf( this->sessionInfo->getSessionId() ); #ifdef HHESOCKET_ERROR HHSOCKETERROR_END #endif
修改ActiveMQSession::disposeOf( Pointer<ProducerId> id )方法,将this->connection->disposeOf( id );改为如下代码:
#ifdef HHESOCKET_ERROR HHSOCKETERROR_START #endif this->connection->disposeOf( id ); #ifdef HHESOCKET_ERROR HHSOCKETERROR_END #endif
修改ActiveMQSession::disposeOf( Pointer<CustomerId> id )方法,将this->connection->disposeOf( id );也改为如上代码
在项目中添加HHESOCKET_ERROR预定义宏,重新编译activemq项目即可