Server SoupWebsocketConnection closed, leaving socket state FIN_WAIT_2 for 2 Minutes
After Client closing the connection, Server closed callback is called, the socket state will be FIN_WAIT_2 for two minutes (I got the state by using windows command netstat -ano | findstr ":8088" ). Two minutes later, the connection seems to be closed completely。
Is this a bug or by design? Or Am I using in the wrong way... Please help
I am using lipsoup 2.74.3. Client and Server on windows.
Server codes:
void soup_websocket_closed_cb(SoupWebsocketConnection* connection, gpointer user_data) {
printf("connection %p closed \n", connection)
}
void soup_websocket_handler(SoupServer* server, SoupWebsocketConnection* connection, const char* path, SoupClientContext* client, gpointer user_data) {
g_signal_connect(G_OBJECT(connection), "closed", G_CALLBACK(soup_websocket_closed_cb), NULL);
printf("connection %p established \n", connection)
}
void start_server() {
int argc = 0;
gst_init(&argc, NULL);
GMainContext *m_context = g_main_context_default();
GMainLoop *m_loop = g_main_loop_new(m_context, false);
SoupServer* m_server = soup_server_new(SOUP_SERVER_SERVER_HEADER, "Demo Server", NULL);
// Set up the request handler
soup_server_add_websocket_handler(m_server, "/test", NULL, NULL,
soup_websocket_handler, NULL, NULL);
// Set the port to listen on
soup_server_listen_all(m_server, 8080, SOUP_SERVER_LISTEN_IPV4_ONLY, NULL);
g_main_loop_run(m_loop);
}
Client codes:
#include "SimpleClient.h"
#include <libsoup/soup.h>
#include <mutex>
#include <thread>
SoupWebsocketConnection* g_connection = NULL;
std::thread* g_thread = NULL;
GMainLoop* g_loop = NULL;
gboolean ServerConnectedCallback(SoupSession* session, GAsyncResult* res,
void* user_data) {
GError* error = NULL;
g_connection = soup_session_websocket_connect_finish(session, res, &error);
soup_websocket_connection_set_keepalive_interval(g_connection, 1);
g_thread = new std::thread([]() {
std::mutex g_lock;
std::condition_variable g_cv;
std::unique_lock<std::mutex> lock(g_lock);
g_cv.wait_for(lock, std::chrono::milliseconds(10000), [] { return false; });
if (g_loop) {
g_main_loop_quit(g_loop);
}
});
return FALSE;
}
std::thread* g_soup_thread = NULL;
int
main (int argc, char *argv[]) {
g_soup_thread = new std::thread([]() {
GMainLoop* loop = g_main_loop_new(NULL, FALSE);
g_loop = loop;
const char* https_aliases[] = {"wss", NULL};
SoupSession* session = soup_session_new_with_options(
SOUP_SESSION_SSL_STRICT, TRUE, SOUP_SESSION_HTTPS_ALIASES,
https_aliases, NULL);
SoupMessage* message =
soup_message_new(SOUP_METHOD_GET, "ws://192.168.6.31:8088/video");
soup_session_websocket_connect_async(
session, message, NULL, NULL, NULL,
(GAsyncReadyCallback)ServerConnectedCallback, NULL);
g_main_loop_run(loop);
if (g_connection) {
soup_websocket_connection_close(g_connection, SOUP_WEBSOCKET_CLOSE_NORMAL,
"client close");
}
g_object_unref(message);
g_object_unref(session);
g_main_loop_unref(loop);
});
while (true) {
g_usleep(1000 * 100);
}
return 0;
}
Edited by li dayong