2016-07-04 24 views
1

私はlibwebsocketを使ってクライアントとサーバとの接続を確立しています。クライアントが要求を送信すると、サーバは応答を送信し、応答を受け取った後にクライアントは接続を閉じます。正常に動作します。libwebsocket:しばらくの間、サーバーの応答がない場合にクライアントを切断する方法(タイムアウトあり)?

しかし、サーバーが要求に応答しないとき、私はクライアントが応答を永遠に待っているという問題があります。何も起こらない場合、コールバックは決して呼び出されず、コールバック関数から-1を返すことで接続を閉じることができません。

接続を閉じるタイムアウトを有効にする方法はありますか?コールバック関数の外部からの接続を閉じる可能性がありますか?ここで

私のコードは、これまでのところです:あなたが使用して試みることができる

int callback_function(libwebsocket_context* context, libwebsocket* wsi, enum libwebsocket_callback_reasons reason, void* user, void* in, size_t len) { 

    switch (reason) { 

     case LWS_CALLBACK_CLIENT_ESTABLISHED: { 
      std::cout << "LWS_CALLBACK_CLIENT_ESTABLISHED" << std::endl; 
      libwebsocket_callback_on_writable(context, wsi); 
     } 
     break; 

     case LWS_CALLBACK_CLOSED:{ 
      std::cout << "LWS_CALLBACK_CLOSED" << std::endl; 
     } 
     break; 

     case LWS_CALLBACK_CLIENT_RECEIVE_PONG: 
     case LWS_CALLBACK_CLIENT_RECEIVE:{ 
      std::cout << "LWS_CALLBACK_CLIENT_RECEIVE" << endl; 
      ((char *)in)[len] = '\0'; 
      answers_[current_request] = answers_[current_request] + string((char *)in); 
      if (libwebsocket_is_final_fragment(wsi)){ 
       std::cout << "request:" << requests_[current_request] << std::endl; 
       std::cout << "answer:" << answers_[current_request] << std::endl; 
       current_request++; 
       if(current_request >= answers_.size()) { 
        ready = true; 

        return -1; 
       } 
       libwebsocket_callback_on_writable(context, wsi); 
      } 
     } 
     break; 

     case LWS_CALLBACK_CLIENT_WRITEABLE:{ 
      std::cout << "LWS_CALLBACK_CLIENT_WRITEABLE" << endl; 
      unsigned char buf[LWS_SEND_BUFFER_PRE_PADDING + 4096 + LWS_SEND_BUFFER_POST_PADDING]; 

      const std::string message = std::string(requests_[current_request]); 

      std::copy(message.begin(), message.end(), &buf[LWS_SEND_BUFFER_PRE_PADDING]); 
      buf[LWS_SEND_BUFFER_PRE_PADDING+(int)message.size()]='\0'; 

      int n = libwebsocket_write(wsi, &buf[LWS_SEND_BUFFER_PRE_PADDING], (size_t)message.size(), static_cast<libwebsocket_write_protocol>(LWS_WRITE_BINARY)); 

      if (n < 0){ 
       std::cout << kLogErr << "bad things are happening" << std::endl; 
       return -1; 
      } 
      if (n < (int)message.size()) { 
       std::cout << kLogErr << "Partial write LWS_CALLBACK_CLIENT_WRITEABLE" << std::endl; 
       return -1; 
      } 
     } 
     break; 

     default: 
      std::cout << "CALLBACK_DEFAULT: " << reason << endl; 
     break; 
    } 

    return 0; 
} 

vector<string> sendMessage(const string& server, int port, const string& path, const vector<string>& messages, bool& error) { 

    ready = error = false; 
    current_request = 0; 

    requests_ = vector<string>(messages); 
    answers_ = vector<string>(requests_.size(), ""); 
    int ietf_version = -1; /* latest */ 
    wsi_ = libwebsocket_client_connect(context_, server.c_str(), port, 2, path.c_str(), server.c_str(), "origin", NULL, ietf_version); 

    if (wsi_ == NULL) { 
     std::cout << kLogErr << "libwebsocket connect failed server:" << server << " port: " << port << " path: " << path << std::endl; 
     error = true; 
     return vector<string>(); 
    } 

    bool first_time = true; 
    int n = 0; 
    while (n >= 0 && !force_exit && !ready) { 
     n = libwebsocket_service(context_, 0); 
     if(first_time) { 
      libwebsocket_callback_on_writable(context_, wsi_); 
      first_time = false; 
     } 
     if (n < 0){ 
      continue; 
     } 
     if (wsi_ == NULL) { 
      break; 
     } 
    } 
    error = !ready; 
    wsi_ = NULL; 
    return vector<string>(answers_); 
} 

答えて

0

私はこの問題を解決しました。

Iは

vector<string> sendMessage(const string& server, int port, const string& path, const vector<string>& messages, bool& error) 

タイマをプログラムし、タイムアウトに達した場合に、タイマーフラグを設定し、再度

libwebsocket_callback_on_writable(context_, wsi_); 

をトリガします。その後

LWS_CALLBACK_CLIENT_WRITEABLE 

場合

int callback_function(libwebsocket_context* context, libwebsocket* wsi, enum libwebsocket_callback_reasons reason, void* user, void* in, size_t len) 

に私はフラグをチェックし、それが設定されている場合、コールバックは

return -1; 

作品罰金で中止され!

0

case LWS_CALLBACK_CLIENT_CONNECTION_ERROR: 
    return -1; 
break; 

それとも

lws_set_timeout 

をしかし、私はそれが動作する100%わからないんだけどあなたはGitHubで問題/質問を作成することもできますが、彼らはかなり速く/明確に答えがちです。

実装する必要があるかわからない

関連する問題