互联网连接丢失时,如何强制关闭Websocket连接?

时间:2019-04-05 18:11:43

标签: c++ websocket uwebsockets

我正在使用uWebsockets的v0.14构建与WebSocket服务器进行交互的WebSocket客户端。我发现Websocket客户端的一个令人烦恼的行为是,当Internet连接断开(出于测试目的,我直接从互联网断开计算机的连接)时,Websocket客户端没有意识到这一点,并且onDisconnectiononError都没有叫做。经过一番谷歌搜索后,我了解到this is an expected behavior,并且我必须手动设置一种ping-pong机制,以使websocket客户端对连接丢失迅速做出反应。我按照建议的方法实现了ping-pong机制,现在当我的客户端未能及时收到一条pong消息时,它成功终止了该客户端,并调用了onDisconnection回调。但是行为仍然很奇怪:在正常断开连接(例如,服务器正常关闭)中,h.run函数在onDisconnection完成后返回。但是,在连接丢失的情况下,h.run即使在onDisconnection完成后也永远不会返回,并且应用程序只是挂在那里。

我的问题是:熟悉uWebSockets的任何人都可以解释如何处理丢失的连接,以便客户端可以快速重试与服务器连接吗?任何建议都欢迎。使用其他库(甚至其他语言)的解决方案也将有所帮助。

以下是我目前的损坏代码:

// This function is called from another thread when connection lost 
// is detected (i.e. when the client fails to receive a `pong` 
// message in time)
void WebSocketClient::force_disconnect_() {
  LOG_ERROR << "trying to force disconnect ws client ...";
  uWS::WebSocket<uWS::CLIENT>* socket_copy = nullptr;
  {
    std::lock_guard<std::mutex> lock(socket_mutex_);
    socket_copy = socket_;
    socket_ = nullptr;
  }
  if (socket_copy) {
    uWS::Group<uWS::CLIENT>::from(socket_copy)->terminate();
    LOG_ERROR << "ws client force disconnected";
  }
}

void WebSocketClient::websocket_thread_func_() {
  uWS::Hub h;
  h.onConnection([this](uWS::WebSocket<uWS::CLIENT> *ws, uWS::HttpRequest req) {
    std::lock_guard<std::mutex> lock(socket_mutex_);
    socket_ = ws;
  });

  h.onDisconnection([&h, this](uWS::WebSocket<uWS::CLIENT> *ws, 
    int code, char* message, size_t length) {
    LOG_INFO << "websocket to " << addr_ << " disconnected with code " << code 
        << ", msg " << std::string(message, length);
    std::lock_guard<std::mutex> lock(socket_mutex_);
    socket_ = nullptr;
    // The callback is called and this line of log is generated
    LOG_INFO << "onDisconnection finish";
  });

  h.onError([&h, this](void* user_data) {
    LOG_ERROR << "error from server";
  });

  h.onPong([this](uWS::WebSocket<uWS::CLIENT> *ws, char* msg, size_t length){
    alive_ = true;
  });

  LOG_INFO << "connecting to " << addr_;
  h.connect(addr_, nullptr);
  // this function never returns
  h.run();
  LOG_INFO << "connection to " << addr_ << " end, websocket thread can be joined.";
}

0 个答案:

没有答案