Rework NetworkClient server initialization to allow interruption and restarting of server list request process when server sends a device list updated notification

This commit is contained in:
Adam Honse 2025-07-04 04:17:25 -05:00
parent 89881bfd7e
commit 4cc6a28e73
2 changed files with 165 additions and 109 deletions

View file

@ -33,9 +33,15 @@ NetworkClient::NetworkClient(std::vector<RGBController *>& control) : controller
{ {
port_ip = "127.0.0.1"; port_ip = "127.0.0.1";
port_num = OPENRGB_SDK_PORT; port_num = OPENRGB_SDK_PORT;
client_string_sent = false;
client_sock = -1; client_sock = -1;
protocol_initialized = false;
server_connected = false; server_connected = false;
server_controller_count = 0; server_controller_count = 0;
server_controller_count_requested = false;
server_controller_count_received = false;
server_protocol_version = 0;
server_reinitialize = false;
change_in_progress = false; change_in_progress = false;
ListenThread = NULL; ListenThread = NULL;
@ -103,7 +109,7 @@ bool NetworkClient::GetConnected()
bool NetworkClient::GetOnline() bool NetworkClient::GetOnline()
{ {
return(server_connected && server_initialized); return(server_connected && client_string_sent && protocol_initialized && server_initialized);
} }
void NetworkClient::RegisterClientInfoChangeCallback(NetClientCallback new_callback, void * new_callback_arg) void NetworkClient::RegisterClientInfoChangeCallback(NetClientCallback new_callback, void * new_callback_arg)
@ -210,8 +216,6 @@ void NetworkClient::StopClient()
void NetworkClient::ConnectionThreadFunction() void NetworkClient::ConnectionThreadFunction()
{ {
unsigned int requested_controllers;
std::unique_lock<std::mutex> lock(connection_mutex); std::unique_lock<std::mutex> lock(connection_mutex);
/*---------------------------------------------------------*\ /*---------------------------------------------------------*\
@ -263,31 +267,24 @@ void NetworkClient::ConnectionThreadFunction()
/*-------------------------------------------------------------*\ /*-------------------------------------------------------------*\
| Double-check client_active as it could have changed | | Double-check client_active as it could have changed |
\*-------------------------------------------------------------*/ \*-------------------------------------------------------------*/
if(client_active && server_initialized == false && server_connected == true) if(client_active && ( protocol_initialized == false || client_string_sent == false || server_initialized == false ) && server_connected == true)
{ {
unsigned int timeout_counter = 0;
requested_controllers = 0;
server_controller_count = 0;
server_controller_count_received = false;
server_protocol_version_received = false;
/*---------------------------------------------------------*\ /*---------------------------------------------------------*\
| Wait for server to connect | | Initialize protocol version if it hasn't already been |
| initialized |
\*---------------------------------------------------------*/ \*---------------------------------------------------------*/
connection_cv.wait_for(lock, 100ms); if(!protocol_initialized)
if(!client_active)
{ {
break; /*-----------------------------------------------------*\
}
/*---------------------------------------------------------*\
| Request protocol version | | Request protocol version |
\*---------------------------------------------------------*/ \*-----------------------------------------------------*/
SendRequest_ProtocolVersion(); SendRequest_ProtocolVersion();
/*---------------------------------------------------------*\ /*-----------------------------------------------------*\
| Wait up to 1s for protocol version reply | | Wait up to 1s for protocol version reply |
\*---------------------------------------------------------*/ \*-----------------------------------------------------*/
unsigned int timeout_counter = 0;
while(!server_protocol_version_received) while(!server_protocol_version_received)
{ {
connection_cv.wait_for(lock, 5ms); connection_cv.wait_for(lock, 5ms);
@ -298,11 +295,11 @@ void NetworkClient::ConnectionThreadFunction()
timeout_counter++; timeout_counter++;
/*---------------------------------------------------------*\ /*-------------------------------------------------*\
| If no protocol version received within 1s, assume the | | If no protocol version received within 1s, assume |
| server doesn't support protocol versioning and use | | the server doesn't support protocol versioning |
| protocol version 0 | | and use protocol version 0 |
\*---------------------------------------------------------*/ \*-------------------------------------------------*/
if(timeout_counter > 200) if(timeout_counter > 200)
{ {
server_protocol_version = 0; server_protocol_version = 0;
@ -310,60 +307,77 @@ void NetworkClient::ConnectionThreadFunction()
} }
} }
protocol_initialized = true;
}
/*---------------------------------------------------------*\ /*---------------------------------------------------------*\
| Once server is connected, send client string | | Send client string if it hasn't already been sent |
\*---------------------------------------------------------*/ \*---------------------------------------------------------*/
if(!client_string_sent)
{
/*-----------------------------------------------------*\
| Once server is connected, send client string |
\*-----------------------------------------------------*/
SendData_ClientString(); SendData_ClientString();
client_string_sent = true;
}
/*---------------------------------------------------------*\ /*---------------------------------------------------------*\
| Request number of controllers | | Initialize the server device list if it hasn't already |
| been initialized |
\*---------------------------------------------------------*/ \*---------------------------------------------------------*/
if(!server_initialized)
{
/*-----------------------------------------------------*\
| Request the server controller count |
\*-----------------------------------------------------*/
if(!server_controller_count_requested)
{
SendRequest_ControllerCount(); SendRequest_ControllerCount();
/*---------------------------------------------------------*\ server_controller_count_requested = true;
| Wait for server controller count |
\*---------------------------------------------------------*/
while(!server_controller_count_received)
{
connection_cv.wait_for(lock, 5ms);
if(!client_active)
{
break;
} }
} else
{
printf("Client: Received controller count from server: %d\r\n", server_controller_count); /*-------------------------------------------------*\
| Wait for the server controller count to be |
/*---------------------------------------------------------*\ | received |
\*-------------------------------------------------*/
if(server_controller_count_received)
{
/*---------------------------------------------*\
| Once count is received, request controllers | | Once count is received, request controllers |
\*---------------------------------------------------------*/ | When data is received, increment count of |
while(requested_controllers < server_controller_count) | requested controllers until all controllers |
| have been received |
\*---------------------------------------------*/
if(requested_controllers < server_controller_count)
{
if(!controller_data_requested)
{ {
printf("Client: Requesting controller %d\r\n", requested_controllers); printf("Client: Requesting controller %d\r\n", requested_controllers);
controller_data_received = false; controller_data_received = false;
SendRequest_ControllerData(requested_controllers); SendRequest_ControllerData(requested_controllers);
/*---------------------------------------------------------*\ controller_data_requested = true;
| Wait until controller is received |
\*---------------------------------------------------------*/
while(controller_data_received == false)
{
connection_cv.wait_for(lock, 5ms);
if(!client_active)
{
break;
}
} }
if(controller_data_received)
{
requested_controllers++; requested_controllers++;
controller_data_requested = false;
} }
}
else
{
ControllerListMutex.lock(); ControllerListMutex.lock();
/*---------------------------------------------------------*\ /*-----------------------------------------*\
| All controllers received, add them to master list | | All controllers received, add them to |
\*---------------------------------------------------------*/ | master list |
\*-----------------------------------------*/
printf("Client: All controllers received, adding them to master list\r\n"); printf("Client: All controllers received, adding them to master list\r\n");
for(std::size_t controller_idx = 0; controller_idx < server_controllers.size(); controller_idx++) for(std::size_t controller_idx = 0; controller_idx < server_controllers.size(); controller_idx++)
{ {
@ -372,20 +386,32 @@ void NetworkClient::ConnectionThreadFunction()
ControllerListMutex.unlock(); ControllerListMutex.unlock();
server_initialized = true; /*-----------------------------------------*\
| Client info has changed, call the |
/*---------------------------------------------------------*\ | callbacks |
| Client info has changed, call the callbacks | \*-----------------------------------------*/
\*---------------------------------------------------------*/
ClientInfoChanged(); ClientInfoChanged();
server_initialized = true;
}
}
}
} }
/*---------------------------------------------------------*\
| Wait 1 ms or until the thread is requested to stop |
\*---------------------------------------------------------*/
connection_cv.wait_for(lock, 1ms);
}
else
{
/*---------------------------------------------------------*\ /*---------------------------------------------------------*\
| Wait 1 sec or until the thread is requested to stop | | Wait 1 sec or until the thread is requested to stop |
\*---------------------------------------------------------*/ \*---------------------------------------------------------*/
connection_cv.wait_for(lock, 1s); connection_cv.wait_for(lock, 1s);
} }
} }
}
int NetworkClient::recv_select(SOCKET s, char *buf, int len, int flags) int NetworkClient::recv_select(SOCKET s, char *buf, int len, int flags)
{ {
@ -524,6 +550,14 @@ void NetworkClient::ListenThreadFunction()
listen_done: listen_done:
printf( "Client socket has been closed"); printf( "Client socket has been closed");
client_string_sent = false;
controller_data_requested = false;
controller_data_received = false;
protocol_initialized = false;
requested_controllers = 0;
server_controller_count = 0;
server_controller_count_requested = false;
server_controller_count_received = false;
server_initialized = false; server_initialized = false;
server_connected = false; server_connected = false;
@ -577,7 +611,12 @@ void NetworkClient::ProcessReply_ControllerCount(unsigned int data_size, char *
if(data_size == sizeof(unsigned int)) if(data_size == sizeof(unsigned int))
{ {
memcpy(&server_controller_count, data, sizeof(unsigned int)); memcpy(&server_controller_count, data, sizeof(unsigned int));
server_controller_count_received = true; server_controller_count_received = true;
requested_controllers = 0;
controller_data_requested = false;
printf("Client: Received controller count from server: %d\r\n", server_controller_count);
} }
} }
@ -642,6 +681,9 @@ void NetworkClient::ProcessRequest_DeviceListChanged()
{ {
change_in_progress = true; change_in_progress = true;
/*---------------------------------------------------------*\
| Delete all controllers from the server's controller list |
\*---------------------------------------------------------*/
ControllerListMutex.lock(); ControllerListMutex.lock();
for(size_t server_controller_idx = 0; server_controller_idx < server_controllers.size(); server_controller_idx++) for(size_t server_controller_idx = 0; server_controller_idx < server_controllers.size(); server_controller_idx++)
@ -673,8 +715,16 @@ void NetworkClient::ProcessRequest_DeviceListChanged()
ClientInfoChanged(); ClientInfoChanged();
/*---------------------------------------------------------*\ /*---------------------------------------------------------*\
| Mark server as uninitialized and delete the list | | Mark server as uninitialized and reset server |
| initialization state so that it restarts the list |
| requesting process |
\*---------------------------------------------------------*/ \*---------------------------------------------------------*/
controller_data_requested = false;
controller_data_received = false;
requested_controllers = 0;
server_controller_count = 0;
server_controller_count_requested = false;
server_controller_count_received = false;
server_initialized = false; server_initialized = false;
change_in_progress = false; change_in_progress = false;

View file

@ -99,14 +99,20 @@ private:
std::string port_ip; std::string port_ip;
unsigned short port_num; unsigned short port_num;
std::atomic<bool> client_active; std::atomic<bool> client_active;
bool client_string_sent;
bool controller_data_received; bool controller_data_received;
bool controller_data_requested;
bool protocol_initialized;
bool server_connected; bool server_connected;
bool server_initialized; bool server_initialized;
bool server_reinitialize;
unsigned int server_controller_count; unsigned int server_controller_count;
bool server_controller_count_requested;
bool server_controller_count_received; bool server_controller_count_received;
unsigned int server_protocol_version; unsigned int server_protocol_version;
bool server_protocol_version_received; bool server_protocol_version_received;
bool change_in_progress; bool change_in_progress;
unsigned int requested_controllers;
std::mutex send_in_progress; std::mutex send_in_progress;
std::mutex connection_mutex; std::mutex connection_mutex;