2016-07-24 106 views
0

我正在使用C++ REST SDK(「卡薩布蘭卡」)從websocket服務器接收提要。如何重新連接到服務器不應答關閉()

有時,我需要關閉連接並重新連接。該庫沒有reconnect函數,因此我關閉了舊連接並簡單地打開一個新連接。問題在於,另一方面,服務器似乎沒有迴應我的密切信息。

這是代碼:

web::websockets::client::websocket_callback_client* m_clClient; 

///... 

void Connection::reconnect() 
{ 
    std::cout << "Debug 1" << std::endl; 
    this->m_clClient.close().get(); 
    delete this->m_clClient; 
    this->m_clClient = new web::websockets::client::websocket_callback_client(); 
    std::cout << "Debug2" << std::endl; 
} 

就像我說的,好像服務器不回答close(),所以程序卡住在this->m_clClient.close().get();永遠。

我也嘗試刪除該會話不發送close(),像這樣:

web::websockets::client::websocket_callback_client* m_clClient; 

///... 

void Connection::reconnect() 
{ 
    std::cout << "Debug 1" << std::endl; 
    delete this->m_clClient; 
    this->m_clClient = new web::websockets::client::websocket_callback_client(); 
    std::cout << "Debug2" << std::endl; 
} 

但節目「調試1」後,仍然被卡住。我認爲close()websocket_callback_client的析構函數中被調用,如果它以前沒有完成的話。

我已經搜索庫的源代碼,發現這裏websocket_callback_client析構函數:link

~wspp_callback_client() 
    { 
     _ASSERTE(m_state < DESTROYED); 
     std::unique_lock<std::mutex> lock(m_wspp_client_lock); 

     // Now, what states could we be in? 
     switch (m_state) { 
     case DESTROYED: 
      // This should be impossible 
      std::abort(); 
     case CREATED: 
      lock.unlock(); 
      break; 
     case CLOSED: 
     case CONNECTING: 
     case CONNECTED: 
     case CLOSING: 
      // Unlock the mutex so connect/close can use it. 
      lock.unlock(); 
      try 
      { 
       // This will do nothing in the already-connected case 
       pplx::task<void>(m_connect_tce).get(); 
      } 
      catch (...) {} 
      try 
      { 
       // This will do nothing in the already-closing case 
       close().wait(); 
      } 
      catch (...) {} 
      break; 
     } 

     // At this point, there should be no more references to me. 
     m_state = DESTROYED; 
} 

正如你可以case CLOSING:下看到它等待連接關閉。

我現在看到的唯一可能性是在不等待答案的情況下調用close(),然後用新客戶端覆蓋指針,而使舊指針取消刪除。這將是一個非常不清楚的解決方案。

我能做些什麼來關閉會話並打開一個新會話?

回答

0

我可以在這一點上看到的唯一的可能性是調用close() 沒有與 新客戶等待的答案,然後覆蓋指針,留下舊未刪除。這將是一個非常不清晰的解決方案。

一些清理可以通過關閉處理器成爲可能:

#include <functional> 
#include <unordered_set> 

#include <cpprest/ws_client.h> 

using namespace std::placeholders; 
using namespace web::websockets::client; 

typedef std::unordered_set<websocket_callback_client *> client_list; 

class Connection 
{ 
public: 
    Connection() : clients() { 
     create_client(); 
    } 

    void reconnect() { 
     create_client(); 
     // connect 
    } 

    void close_handler(websocket_callback_client * client, 
       websocket_close_status status, 
       const utility::string_t & reason, 
       const std::error_code & ec) { 
    // check status and/or ec first? 
    clients.erase(client); 
    delete client; 

    // perform automatic reconnect if some flag tells so? 
    } 
protected: 
    void create_client() { 
     client = new websocket_callback_client(); 
     clients.insert(client); 
     client->set_close_handler(std::bind(&Connection::close_handler, this, 
              client, _1, _2, _3)); 
    } 

    websocket_callback_client * client; 
    client_list clients; 
}; 

由於張貼在問題的代碼是不是一個完整的程序,我無法測試我的解決方案不同的是它編譯(鐺++/G ++ )。

+0

我編輯了我的問題並添加了更多詳細信息。不幸的是,由於析構函數仍然會等待它,所以不能使用get()。唯一的解決方案是在不帶'get()'的情況下調用'close()',然後覆蓋指針,從而使舊客戶端不被刪除。 – Bobface

0

我遇到了這個問題,以及我遇到問題的原因是由於我試圖從close處理程序清理websocket_callback_client。如果我不這樣做,它似乎清理自己了不起。

相關問題