Я использую v0.14 из uWebsockets для создания клиента websocket, который взаимодействует с сервером websocket.Раздражающее поведение, которое я обнаружил в клиенте websocket, заключается в том, что при потере интернет-соединения (я отключаю компьютер от интернета напрямую для тестирования), клиент websocket не осознает этого и не вызывает ни onDisconnection
, ни onError
.После некоторого поиска в Google, я понял, что это ожидаемое поведение , и мне пришлось вручную настроить механизм 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.";
}