Ich verwende die C++ REST SDK
("Casablanca"), um Feed von Websocket-Servern zu empfangen.Verbindung mit einem Server herstellen, der nicht auf Schließen antwortet()
Manchmal muss ich die Verbindung schließen und erneut verbinden. Die Bibliothek hat keine reconnect
Funktion, also schließe ich die alte Verbindung und öffne einfach eine neue. Das Problem ist, dass der Server auf der anderen Seite, wie es scheint, nicht auf meine nahe Nachricht antwortet.
Dies ist der Code:
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;
}
Wie gesagt, scheint es, wie der Server close()
nicht antwortet, so wird das Programm bei this->m_clClient.close().get();
für immer fest.
Ich habe auch versucht, die Sitzung zu löschen, ohne ein close()
zu senden, etwa so:
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;
}
Aber das Programm noch nach dem "Debug 1" stecken bleibt. Ich denke, die close()
wird im Destruktor websocket_callback_client
aufgerufen, wenn es nicht zuvor getan wurde.
ich den Quellcode der Bibliothek gesucht und gefunden haben, die destructor von websocket_callback_client
hier: 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;
}
Wie Sie unter case CLOSING:
sehen wartet er auf die Verbindung zu schließen.
Die einzige Möglichkeit, die ich an dieser Stelle sehen kann, ist close()
ohne Warten auf die Antwort und dann den Zeiger mit einem neuen Client überschreiben, so dass die alte gelöscht. Dies wäre eine sehr unreine Lösung.
Was kann ich tun, um die Sitzung zu schließen und eine neue zu öffnen?
Ich habe meine Frage bearbeitet und weitere Details hinzugefügt. Leider ist es nicht möglich, 'get()' wegzulassen, da der Destruktor immer noch darauf wartet. Die einzige Lösung wäre, 'close()' ohne 'get()' aufzurufen und dann den Zeiger zu überschreiben, wobei der alte Client nicht gelöscht wird. – Bobface