0

我目前正在构建一个 C Tasker,该程序的目标是通过 Websockets 连接到主服务器并尽可能保持连接活动(客户端看门狗)。

同时,Tasker 应该能够从客户端(服务器行为)接收 Json,相应地处理它们并回答。

为此,我使用 GLib 的多线程方法和网络部分的 Libwebsockets 库。

C 客户端/服务器 Tasker 运行良好,因此下一步应该是:当与主服务器的连接丢失时,尝试“永远”重新连接,直到主服务器启动,或者在另一个主服务器上回退。

这里的问题是,当我切断与服务器的连接时,看门狗线程似乎忽略了重新连接。由于线程与 libwesockets 回调完全隔离。

以下是代码片段:

在Tasker Server init中调用Tasker Client

       int janus_websockets_init(janus_transport_callbacks *callback, const char *config_path) {            
  if(g_atomic_int_get(&stopping)) {                                                                  

    return -1;                                                                                       
  }                                                                                                  
  if(callback == NULL || config_path == NULL)                                                        
    return -1;                                                                                       
        gateway = callback;                                                                          

        Client_start() 

塔斯克服务器配置

 struct lws_context_creation_info info;                                       
                        memset(&info, 0, sizeof info);                                               
                        info.port = wsport;                                                          
                        info.iface = ip ? ip : interface;                                            
                        info.protocols = wss_protocols;                                              
                        info.extensions = NULL;                                                      
                        info.ssl_cert_filepath = NULL;                                               
                        info.ssl_private_key_filepath = NULL;                                        
                        info.gid = -1;                                                               
                        info.uid = -1;                                                               
                        info.options = 0;                                                            
                        /* Create the WebSocket context */                                           
                        wss = lws_create_context(&info);                                             
                        if(wss == NULL) {                                                            
                                ZETA_LOG(LOG_FATAL, "Error initializing libwebsockets...\n");        
                        } else {                                                                     
                                ZETA_LOG(LOG_INFO, "WebSockets server started (port %d)...\n", wspor\
t);                                                                                                  
                        }  

塔斯克客户端配置

整数

Client_start()                                                                                   
{                                                                                                    
  //* register the signal SIGINT handler */                                                          

  struct lws_context_creation_info info;                                                             

  memset(&info, 0, sizeof info);                                                                     
  info.port = CONTEXT_PORT_NO_LISTEN;                                                                
  info.iface = NULL;                                                                                 
  info.protocols = wss_protocols;                                                                    
  info.ssl_cert_filepath = NULL;                                                                     
  info.ssl_private_key_filepath = NULL;                                                              
  info.extensions = lws_get_internal_extensions();                                                   
  info.gid = -1;                                                                                     
  info.uid = -1;                                                                                     
  info.options = 0;                                                                                  

  protocol.name  = "janus-protocol";                                                                 
  protocol.callback = &ws_client_service_callback;                                                   
  protocol.per_session_data_size = sizeof(struct session_data);                                      
  protocol.rx_buffer_size = 0;                                                                       
  protocol.id = 0;                                                                                   
  protocol.user = NULL;                                                                              

  context = lws_create_context(&info); 

Tasker 客户端看门狗线程调用

if (context == NULL) {                                                                             
    printf(KRED"[Main Service] context is NULL.\n"RESET);                                            
    return -1;                                                                                       
  }                                                                                                  

  wsz = lws_client_connect(context, "xxx.xxx.xxx.xxx",5000, 0,                                       
                           "/", "xxx.xxx.xxx.xxx:5000", NULL,                                        
                           protocol.name, -1);                                                       

  if (wsz == NULL) {                                                                                 
    printf(KRED"[Main] wsi create error.\n"RESET);                                                   
    return -1;                                                                                       
  }                                                                                                  
  reco = false;                                                                                      
  printf(KGRN"[Main] wsi create success.\n"RESET);                                                   

  printf(KRED"[Main Service] %d\n", ConnOk, RESET);                                                  

  keepAlive =  g_thread_try_new("KeepAliveLoop", keep_alive_routine, context, NULL);                 

  while(!dead)                                                                                       
    lws_service(context, 50);                                                                        

  lws_context_destroy(context);                                                                      

  return 0;                                                                                          
}   

Finnaly The Tasker Client 线程例程循环和线程循环执行代码

static void keep_alive_loop()                                                                        
{                                                                                                    
  json_t *hb = NULL;                                                                                 
  char *toto = NULL;                                                                                 

    if (reco == true)                                                                                
   {                                                                                                 
     wsz = lws_client_connect(context, "xxx.xxx.xxx.xxx",5000, 0,                                    
                              "/", "xxx.xxx.xxx.xxx:5000", NULL,                                     
                              protocol.name, -1);                                                    
     printf(KRED"[Main Service] UNDER LOOOOOOPING .\n"RESET);                                        
     reco = false;                                                                                   
     return;                                                                                         
   }                                                                                                 

    hb = json_object();                                                                              
    json_object_set_new(hb, "zetapush", json_string("keepalive"));                                   
    json_object_set_new(hb, "timeout", json_integer(8000));                                          
    toto = json_dumps(hb, 0);                                                                        
    websocket_client_keep_alive_write_back(hb);                                                      
    lws_callback_on_writable(wsz);                                                                   
}                                                                                                    

static void *keep_alive_routine(void *data)                                                          
{                                                                                                    
  printf(KBRN"[pthread_routine] WATCHDOG READY AND ANGRY .\n"RESET);                                 

  g_timeout_add_seconds(8, keep_alive_loop, NULL);                                                   
  alive_loop = g_main_loop_new(NULL, 0);                                                             
  g_main_loop_run(alive_loop);                                                                       
}  

如果需要任何进一步的精度让我知道,我也可以上传到 github 以便更好地阅读,任何帮助或提示将不胜感激:)。

4

0 回答 0