1
votes

I tried to put a QWebSocket connection into a QThread

QThread *thread = new QThread;



connect(&websocket,&QWebSocket::connected,this,&Widget::onWsConnect);

websocket.moveToThread(thread);
connect(thread, &QThread::finished, &websocket, &QObject::deleteLater);
websocket.open(wsUrl);

thread->start();

The program compiled without errors and is running normal, but when it tried to connect to the websocket server throws this error:

QObject::connect: Cannot queue arguments of type 'QAbstractSocket::SocketState' (Make sure 'QAbstractSocket::SocketState' is registered using qRegisterMetaType().)

When I do

websocket.open(wsUrl);

without threading the connection works fine.

Any ideas?

3

3 Answers

2
votes

If you want to send your object through queued signal/slot connections, you should use qRegisterMetaType<T>(). Just call it before opening the socket some where in the constructor :

qRegisterMetaType<QAbstractSocket::SocketState>();
2
votes

The previous (Nejat's) answer is good as direct answer on how to attach the signal to slot in this case. But why do you want to start the web-socket on an additional thread? I start that same Qt WebSocket from main thread and it does no block it. The time to start that type of socket itself is negligible. I guess websocket uses some kind of OS non-blocking IO (likeliest) or spawns another thread internally (less likely). Other than blocking or doing massive computation you probably don't have a good reason for spawning a new thread and then taking care of managing it and additional communication overhead.

1
votes

My suggestion would be to maintain a list of open websocket connections, and when a particular connection gets a request, spawn a thread to handle the request and continue processing new connections/requests on the main thread. Then, when the thread is done processing the request, it signals the main thread that it's done, along with the response. The main thread would then receive the response from the thread and send it out over the open connection. You could use std::async and std::future to accomplish this.