I'm trying to get C++ HRC working but am not having any luck. This is how we are testing:
1. Use SmartFox::killConnection() to simulate a connection going away - this is tied to a button inside our game
2. When we trigger a killConnection(), we see that the CONNECTION_RETRY event is fired in the client and also the equivalent in the server
3. CONNECTION_RESUME event is never fired.
4. We've tested using both the newest 1.6.0 API as well as the previous 1.1.6 API - both have the same problem and behave identically in these tests and trial/error modifications
5. The zone configuration on the server has reconnection seconds set to 15
Because we have the C++ source code to the SFS2X Client API, we walked through in our debugger and tried to find the cause of the issue. We see that the client is aware that it should fire a CONNECTION_RETRY event and goes into the following call sequence:
1. SmartFox::OnSocketReconnectionTry() - this fires the SFSEvent::CONNECTION_RETRY event back to our client and we do get this successfully
2. BitSwarmClient::RetryConnection() is called which ends up calling BitSwarmClient::OnRetryConnectionEvent() using a retryTimer
3. BitSwarmClient::OnRetryConnectionEvent() calls socket->Connect(address, lastTcpPort)
4. This goes into TCPSocketLayer::Connect() which fails at the following code:
Code: Select all
if (State() != States_Disconnected)
{
boost::shared_ptr<string> message (new string("Calling connect when the socket is not disconnected"));
LogWarn(message);
return;
}
It returns because the TCPSocketLayer state is not Disconnected
To try things further, we changed BitSwarmClient::OnRetryConnectionEvent() and before calling socket->Connect(address, lastTcpPort), we do a socket->Disconnect(). Doing this, we are able to get a physical socket reconnection and sometimes we can get the resume to fully work with this change. Other times it will crash and more rarely, it will attempt to reconnect but not complete through to CONNECTION_RESUME without crashing. Our new code for TCPSocketLayer::OnRetryConnectionEvent() looks like this:
Code: Select all
void BitSwarmClient::OnRetryConnectionEvent(const boost::system::error_code& code)
{
if (code == boost::asio::error::operation_aborted)
{
// Timer has been stopped
// Nothing to do
return;
}
if(socket->IsConnected()) {
socket->Disconnect();
}
boost::shared_ptr<IPAddress> address (new IPAddress(IPAddress::IPADDRESSTYPE_IPV4, *lastIpAddress));
socket->Connect(address, lastTcpPort);
}
Doing this, we can see that sometimes the connection resumes normally. Other times it will crash with a SIGABRT doing this boost::lock_guard<boost::recursive_mutex> lock(mtxDisconnection); in the following code block:
Code: Select all
void TCPClient::OnBoostAsioDataReceived(const boost::system::error_code& error, long int length)
{
boost::shared_ptr<vector<unsigned char> > data;
if (length > 0)
{
data = boost::shared_ptr<vector<unsigned char> >(new vector<unsigned char>());
data->assign((unsigned char*)(boostTcpInputBuffer.data()), (unsigned char*)(boostTcpInputBuffer.data() + length));
}
else
{
data = boost::shared_ptr<vector<unsigned char> >(new vector<unsigned char>());
}
// Notify received data
// Note that data length could be 0 when socket closure has been detected
boost::lock_guard<boost::recursive_mutex> lock(mtxDisconnection);
if (callbackTCPDataRead != NULL)
{
callbackTCPDataRead->Invoke(data);
}
boost::lock_guard<boost::recursive_mutex> unlock(mtxDisconnection);
// Decrease counter of asynchronous read that are in progress
if (counterAsyncReadOperationsInProgress > 0)
{
#if defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) || defined( __CYGWIN__ )
BOOST_INTERLOCKED_DECREMENT(&counterAsyncReadOperationsInProgress);
#else
counterAsyncReadOperationsInProgress--;
#endif
}
}
Can someone help us fix this and get HRC working on C++? It looks like there is now lock contention and multiple threads are trying to acquire the same lock that is causing that failure. If we can get past that, it looks like forcing a socket disconnect before trying to reconnect will get HRC working for the C++ SFS2X API.
Thanks!