Issue 13: Added support for connect sequence timeout

Decreased the select timeout when reading headers
Don't call callback with DISCONNECTED if the connection was never connected
This commit is contained in:
JCash 2020-10-17 11:40:53 +02:00
parent 9d1ace0a82
commit e105702c79
4 changed files with 43 additions and 8 deletions

View File

@ -17,6 +17,9 @@
type: table type: table
desc: optional parameters as properties. The following parameters can be set desc: optional parameters as properties. The following parameters can be set
members: members:
- name: timeout
type: number
desc: Timeout for the connection sequence (milliseconds)
- name: callback - name: callback
type: function type: function

View File

@ -105,13 +105,13 @@ Result ReceiveHeaders(WebsocketConnection* conn)
dmSocket::SelectorZero(&selector); dmSocket::SelectorZero(&selector);
dmSocket::SelectorSet(&selector, dmSocket::SELECTOR_KIND_READ, conn->m_Socket); dmSocket::SelectorSet(&selector, dmSocket::SELECTOR_KIND_READ, conn->m_Socket);
dmSocket::Result sr = dmSocket::Select(&selector, 200*1000); dmSocket::Result sr = dmSocket::Select(&selector, SOCKET_WAIT_TIMEOUT);
if (dmSocket::RESULT_OK != sr) if (dmSocket::RESULT_OK != sr)
{ {
if (dmSocket::RESULT_WOULDBLOCK) if (dmSocket::RESULT_WOULDBLOCK)
{ {
dmLogWarning("Waiting for socket to be available for reading"); DebugLog(1, "Waiting for socket to be available for reading");
return RESULT_WOULDBLOCK; return RESULT_WOULDBLOCK;
} }

View File

@ -178,6 +178,7 @@ static WebsocketConnection* CreateConnection(const char* url)
conn->m_Buffer = (char*)malloc(conn->m_BufferCapacity); conn->m_Buffer = (char*)malloc(conn->m_BufferCapacity);
conn->m_Buffer[0] = 0; conn->m_Buffer[0] = 0;
conn->m_BufferSize = 0; conn->m_BufferSize = 0;
conn->m_ConnectTimeout = 0;
dmURI::Parts uri; dmURI::Parts uri;
dmURI::Parse(url, &conn->m_Url); dmURI::Parse(url, &conn->m_Url);
@ -194,6 +195,7 @@ static WebsocketConnection* CreateConnection(const char* url)
conn->m_SSLSocket = 0; conn->m_SSLSocket = 0;
conn->m_Status = RESULT_OK; conn->m_Status = RESULT_OK;
conn->m_HasHandshakeData = 0; conn->m_HasHandshakeData = 0;
conn->m_WasConnected = 0;
#if defined(HAVE_WSLAY) #if defined(HAVE_WSLAY)
conn->m_Ctx = 0; conn->m_Ctx = 0;
@ -265,13 +267,12 @@ static int LuaConnect(lua_State* L)
const char* url = luaL_checkstring(L, 1); const char* url = luaL_checkstring(L, 1);
// long playedTime = luaL_checktable_number(L, 2, "playedTime", -1);
// long progressValue = luaL_checktable_number(L, 2, "progressValue", -1);
// char *description = luaL_checktable_string(L, 2, "description", NULL);
// char *coverImage = luaL_checktable_string(L, 2, "coverImage", NULL);
WebsocketConnection* conn = CreateConnection(url); WebsocketConnection* conn = CreateConnection(url);
// milliseconds
lua_Number timeout = dmScript::CheckTableNumber(L, 2, "timeout", 3000);
conn->m_ConnectTimeout = dmTime::GetTime() + timeout * 1000;
conn->m_Callback = dmScript::CreateCallback(L, 3); conn->m_Callback = dmScript::CreateCallback(L, 3);
if (g_Websocket.m_Connections.Full()) if (g_Websocket.m_Connections.Full())
@ -528,6 +529,13 @@ Result PushMessage(WebsocketConnection* conn, MessageType type, int length, cons
return dmWebsocket::RESULT_OK; return dmWebsocket::RESULT_OK;
} }
// has the connect procedure taken too long?
static bool CheckConnectTimeout(WebsocketConnection* conn)
{
uint64_t t = dmTime::GetTime();
return t >= conn->m_ConnectTimeout;
}
static dmExtension::Result OnUpdate(dmExtension::Params* params) static dmExtension::Result OnUpdate(dmExtension::Params* params)
{ {
uint32_t size = g_Websocket.m_Connections.Size(); uint32_t size = g_Websocket.m_Connections.Size();
@ -544,7 +552,10 @@ static dmExtension::Result OnUpdate(dmExtension::Params* params)
conn->m_BufferSize = 0; conn->m_BufferSize = 0;
} }
if (conn->m_WasConnected)
{
HandleCallback(conn, EVENT_DISCONNECTED, 0, conn->m_BufferSize); HandleCallback(conn, EVENT_DISCONNECTED, 0, conn->m_BufferSize);
}
g_Websocket.m_Connections.EraseSwap(i); g_Websocket.m_Connections.EraseSwap(i);
--i; --i;
@ -609,6 +620,12 @@ static dmExtension::Result OnUpdate(dmExtension::Params* params)
} }
else if (STATE_HANDSHAKE_READ == conn->m_State) else if (STATE_HANDSHAKE_READ == conn->m_State)
{ {
if (CheckConnectTimeout(conn))
{
CLOSE_CONN("Connect sequence timed out");
continue;
}
Result result = ReceiveHeaders(conn); Result result = ReceiveHeaders(conn);
if (RESULT_WOULDBLOCK == result) if (RESULT_WOULDBLOCK == result)
{ {
@ -645,11 +662,18 @@ static dmExtension::Result OnUpdate(dmExtension::Params* params)
#endif #endif
dmSocket::SetBlocking(conn->m_Socket, false); dmSocket::SetBlocking(conn->m_Socket, false);
conn->m_WasConnected = 1;
SetState(conn, STATE_CONNECTED); SetState(conn, STATE_CONNECTED);
HandleCallback(conn, EVENT_CONNECTED, 0, 0); HandleCallback(conn, EVENT_CONNECTED, 0, 0);
} }
else if (STATE_HANDSHAKE_WRITE == conn->m_State) else if (STATE_HANDSHAKE_WRITE == conn->m_State)
{ {
if (CheckConnectTimeout(conn))
{
CLOSE_CONN("Connect sequence timed out");
continue;
}
Result result = SendClientHandshake(conn); Result result = SendClientHandshake(conn);
if (RESULT_WOULDBLOCK == result) if (RESULT_WOULDBLOCK == result)
{ {
@ -665,6 +689,12 @@ static dmExtension::Result OnUpdate(dmExtension::Params* params)
} }
else if (STATE_CONNECTING == conn->m_State) else if (STATE_CONNECTING == conn->m_State)
{ {
if (CheckConnectTimeout(conn))
{
CLOSE_CONN("Connect sequence timed out");
continue;
}
#if defined(__EMSCRIPTEN__) #if defined(__EMSCRIPTEN__)
conn->m_SSLSocket = dmSSLSocket::INVALID_SOCKET_HANDLE; conn->m_SSLSocket = dmSSLSocket::INVALID_SOCKET_HANDLE;

View File

@ -89,6 +89,7 @@ namespace dmWebsocket
dmSocket::Socket m_Socket; dmSocket::Socket m_Socket;
dmSSLSocket::Socket m_SSLSocket; dmSSLSocket::Socket m_SSLSocket;
dmArray<Message> m_Messages; // lengths of the messages in the data buffer dmArray<Message> m_Messages; // lengths of the messages in the data buffer
uint64_t m_ConnectTimeout;
uint8_t m_Key[16]; uint8_t m_Key[16];
State m_State; State m_State;
char* m_Buffer; char* m_Buffer;
@ -97,6 +98,7 @@ namespace dmWebsocket
Result m_Status; Result m_Status;
uint8_t m_SSL:1; uint8_t m_SSL:1;
uint8_t m_HasHandshakeData:1; uint8_t m_HasHandshakeData:1;
uint8_t m_WasConnected:1;
uint8_t :6; uint8_t :6;
}; };