fix crash on close

This commit is contained in:
dimon4eg 2019-05-11 12:07:25 +03:00
parent 6cd970d0d9
commit ef2e5c7ddb
3 changed files with 57 additions and 59 deletions

View File

@ -149,7 +149,6 @@ namespace ix
// This value needs to be forced when shutting down, it is restored later
_automaticReconnection = false;
// sync close
close();
if (_thread.joinable())
@ -218,72 +217,63 @@ namespace ix
return getReadyState() == WebSocket_ReadyState_Closing;
}
bool WebSocket::isConnectedOrClosing() const
{
return isConnected() || isClosing();
}
void WebSocket::close()
{
_ws.close();
}
void WebSocket::reconnectPerpetuallyIfDisconnected()
void WebSocket::checkConnection(bool initial)
{
uint32_t retries = 0;
WebSocketErrorInfo connectErr;
ix::WebSocketInitResult status;
using millis = std::chrono::duration<double, std::milli>;
millis duration;
// Try to connect only once when we don't have automaticReconnection setup
if (!isConnectedOrClosing() && !_stop && !_automaticReconnection)
uint32_t retries = 0;
millis duration;
ix::WebSocketInitResult status;
// we will try to connect perpertually
while (true)
{
if (isConnected() || isClosing() || _stop)
{
break;
}
if (!initial && !_automaticReconnection)
{
// don't attempt to reconnect
break;
}
initial = false;
// Only sleep if we are retrying
if (duration.count() > 0)
{
// to do: make conditional sleeping
std::this_thread::sleep_for(duration);
}
// try to connect (sync connect)
status = connect(_handshakeTimeoutSecs);
if (!status.success)
{
duration = millis(calculateRetryWaitMilliseconds(retries++));
WebSocketErrorInfo connectErr;
connectErr.retries = retries;
connectErr.wait_time = duration.count();
connectErr.reason = status.errorStr;
connectErr.http_status = status.http_status;
_onMessageCallback(WebSocket_MessageType_Error, "", 0,
connectErr, WebSocketOpenInfo(),
WebSocketCloseInfo());
}
}
else
{
// Otherwise try to reconnect perpertually
while (true)
{
if (isConnectedOrClosing() || _stop || !_automaticReconnection)
{
break;
}
status = connect(_handshakeTimeoutSecs);
if (!status.success)
if (_automaticReconnection)
{
duration = millis(calculateRetryWaitMilliseconds(retries++));
connectErr.retries = retries;
connectErr.wait_time = duration.count();
connectErr.reason = status.errorStr;
connectErr.http_status = status.http_status;
_onMessageCallback(WebSocket_MessageType_Error, "", 0,
connectErr, WebSocketOpenInfo(),
WebSocketCloseInfo());
// Only sleep if we aren't in the middle of stopping
if (!_stop)
{
std::this_thread::sleep_for(duration);
}
connectErr.retries = retries;
}
connectErr.reason = status.errorStr;
connectErr.http_status = status.http_status;
_onMessageCallback(WebSocket_MessageType_Error, "", 0,
connectErr, WebSocketOpenInfo(),
WebSocketCloseInfo());
}
}
}
@ -292,10 +282,20 @@ namespace ix
{
setThreadName(getUrl());
while (getReadyState() != WebSocket_ReadyState_Closed)
bool initial = true;
while (true)
{
// 1. Make sure we are always connected
reconnectPerpetuallyIfDisconnected();
checkConnection(initial);
initial = false;
// if here we are closed then checkConnection was not able to connect
if (getReadyState() == WebSocket_ReadyState_Closed)
{
break;
}
// 2. Poll to see if there's any new data available
WebSocketTransport::PollPostTreatment pollPostTreatment = _ws.poll();
@ -311,6 +311,7 @@ namespace ix
WebSocketMessageType webSocketMessageType;
switch (messageKind)
{
default:
case WebSocketTransport::MSG:
{
webSocketMessageType = WebSocket_MessageType_Message;
@ -341,9 +342,6 @@ namespace ix
WebSocket::invokeTrafficTrackerCallback(msg.size(), true);
});
// If we aren't trying to reconnect automatically, exit if we aren't connected
if (!isConnectedOrClosing() && !_automaticReconnection) return;
}
}

View File

@ -99,6 +99,7 @@ namespace ix
// Run asynchronously, by calling start and stop.
void start();
// stop is synchronous
void stop();
// Run in blocking mode, by connecting first manually, and then calling run.
@ -135,8 +136,7 @@ namespace ix
bool isConnected() const;
bool isClosing() const;
bool isConnectedOrClosing() const;
void reconnectPerpetuallyIfDisconnected();
void checkConnection(bool initial);
std::string readyStateToString(ReadyState readyState);
static void invokeTrafficTrackerCallback(size_t size, bool incoming);

View File

@ -12,10 +12,10 @@ namespace ix
{
struct WebSocketErrorInfo
{
uint32_t retries;
double wait_time;
int http_status;
uint32_t retries = 0;
double wait_time = 0;
int http_status = 0;
std::string reason;
bool decompressionError;
bool decompressionError = false;
};
}