0

プログラムの目標は、Websockets を介してメイン サーバーに接続し、可能な限り接続を維持することです (クライアント ウォッチドッグ)。

その間、Tasker はクライアントから Json を受信し (Server Behaviour)、それに応じて処理し、応答する必要があります。

これを実行するには、GLib のマルチスレッド メソッドと、ネットワーク部分の Libwebsockets ライブラリを使用します。

C Client/Server 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;                                                                                          
}   

最後に、Tasker クライアントのスレッド ルーチン ループとスレッド ループの実行コード

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