QWebSocketServer and QThread
-
Hello everyone. for some reasons, namely when a user fills a stream, others do not have access to the server,
I need to make separate threads on QWebSocket, so I know that QWebSocket cannot be passed to other threads, so I wrote an example in which QTcpServer -> socketDescriptor - > QThread -> QTcpSocket -> QWebSocketServer::handleConnection and accordingly via newConnection I get a QWebSocket,
the connection is established and the data is received by the server and can be processed, but when I try to send back to the client nothing happens except one error in the console,QSocketNotifier: Socket notifiers cannot be enabled or disabled from another threadhere is a simple example server, tested from the standard echoclient example
if you do not transfer the work of QWebSocketServer to a heavy thread, then everything works.
maybe someone has some idea what the problem is, or has faced such before.Thank you for attention.
example
main.cpp#include <QCoreApplication> #include "TcpServerMultithreading.h" int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); TcpServerMultithreading serverTcp(1551); return a.exec(); }TcpServerMultithreading.h
#ifndef TCPSERVERMULTITHREADING_H #define TCPSERVERMULTITHREADING_H #include <QObject> #include <QTcpServer> #include <QTcpSocket> #include <QtWebSockets/QWebSocketServer> #include <QtWebSockets/QWebSocket> class TcpServerMultithreading : public QTcpServer { Q_OBJECT public: explicit TcpServerMultithreading(quint16 port, QObject *parent = nullptr); protected: void incomingConnection(qintptr socketDescriptor) override; public slots: void parseMessage(const QString &message); void onNewConnection(); private: int socketDescriptor; QWebSocketServer *m_pWebSocketServer; }; #endif // TCPSERVERMULTITHREADING_HTcpServerMultithreading.cpp
#include "TcpServerMultithreading.h" #include "UserConnectThread.h" TcpServerMultithreading::TcpServerMultithreading(quint16 port, QObject *parent) : QTcpServer{parent} { if (listen(QHostAddress::Any, port)) { qDebug() << "SSL Echo Server listening on port" << serverPort(); } else { qDebug() << "ERROR: " << errorString(); } } void TcpServerMultithreading::incomingConnection(qintptr socketDescriptor) { qDebug() << Q_FUNC_INFO << socketDescriptor; UserConnectThread *userConnectThread = new UserConnectThread(socketDescriptor, this); userConnectThread->start(); } void TcpServerMultithreading::parseMessage(const QString &message) { qDebug() << Q_FUNC_INFO << message; QWebSocket *pClient = qobject_cast<QWebSocket *>(sender()); pClient->sendTextMessage(QString("return: %1").arg(message)); } void TcpServerMultithreading::onNewConnection() { qDebug() << Q_FUNC_INFO; QWebSocket *m_pSocket = m_pWebSocketServer->nextPendingConnection(); connect(m_pSocket, &QWebSocket::textMessageReceived, this, &TcpServerMultithreading::parseMessage); }UserConnectThread.h
#ifndef USERCONNECTTHREAD_H #define USERCONNECTTHREAD_H #include <QObject> #include <QThread> #include <QTcpSocket> #include <QtWebSockets/QWebSocketServer> #include <QtWebSockets/QWebSocket> class UserConnectThread : public QThread { Q_OBJECT public: explicit UserConnectThread(int socketDescriptor, QObject *parent = nullptr); void run() override; signals: void sendToClient(QString message); public slots: void parseMessage(const QString &message); void onNewConnection(); private: int socketDescriptor; QWebSocketServer *m_pWebSocketServer; }; #endif // USERCONNECTTHREAD_HUserConnectThread.cpp
#include "UserConnectThread.h" UserConnectThread::UserConnectThread(int socketDescriptor, QObject *parent) : QThread{parent}, socketDescriptor(socketDescriptor) { } void UserConnectThread::run() { qDebug() << "Run Thread"; QTcpSocket *tcpSocket = new QTcpSocket(); if (!tcpSocket->setSocketDescriptor(socketDescriptor)) { //emit error(tcpSocket->error()); return; } m_pWebSocketServer = new QWebSocketServer(QStringLiteral("SSL Echo Server"), QWebSocketServer::NonSecureMode); connect(m_pWebSocketServer, &QWebSocketServer::newConnection, this, &UserConnectThread::onNewConnection); m_pWebSocketServer->handleConnection(tcpSocket); exec(); } void UserConnectThread::parseMessage(const QString &message) { qDebug() << Q_FUNC_INFO << message; QWebSocket *pClient = qobject_cast<QWebSocket *>(sender()); int sizeSend = pClient->sendTextMessage(QString("return: %1").arg(message)); qDebug() << Q_FUNC_INFO << "send: " << sizeSend; } void UserConnectThread::onNewConnection() { qDebug() << Q_FUNC_INFO; QWebSocket *m_pSocket = m_pWebSocketServer->nextPendingConnection(); connect(m_pSocket, &QWebSocket::textMessageReceived, this, &UserConnectThread::parseMessage); connect(this, &UserConnectThread::sendToClient, m_pSocket, &QWebSocket::sendTextMessage); } -
Hello everyone. for some reasons, namely when a user fills a stream, others do not have access to the server,
I need to make separate threads on QWebSocket, so I know that QWebSocket cannot be passed to other threads, so I wrote an example in which QTcpServer -> socketDescriptor - > QThread -> QTcpSocket -> QWebSocketServer::handleConnection and accordingly via newConnection I get a QWebSocket,
the connection is established and the data is received by the server and can be processed, but when I try to send back to the client nothing happens except one error in the console,QSocketNotifier: Socket notifiers cannot be enabled or disabled from another threadhere is a simple example server, tested from the standard echoclient example
if you do not transfer the work of QWebSocketServer to a heavy thread, then everything works.
maybe someone has some idea what the problem is, or has faced such before.Thank you for attention.
example
main.cpp#include <QCoreApplication> #include "TcpServerMultithreading.h" int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); TcpServerMultithreading serverTcp(1551); return a.exec(); }TcpServerMultithreading.h
#ifndef TCPSERVERMULTITHREADING_H #define TCPSERVERMULTITHREADING_H #include <QObject> #include <QTcpServer> #include <QTcpSocket> #include <QtWebSockets/QWebSocketServer> #include <QtWebSockets/QWebSocket> class TcpServerMultithreading : public QTcpServer { Q_OBJECT public: explicit TcpServerMultithreading(quint16 port, QObject *parent = nullptr); protected: void incomingConnection(qintptr socketDescriptor) override; public slots: void parseMessage(const QString &message); void onNewConnection(); private: int socketDescriptor; QWebSocketServer *m_pWebSocketServer; }; #endif // TCPSERVERMULTITHREADING_HTcpServerMultithreading.cpp
#include "TcpServerMultithreading.h" #include "UserConnectThread.h" TcpServerMultithreading::TcpServerMultithreading(quint16 port, QObject *parent) : QTcpServer{parent} { if (listen(QHostAddress::Any, port)) { qDebug() << "SSL Echo Server listening on port" << serverPort(); } else { qDebug() << "ERROR: " << errorString(); } } void TcpServerMultithreading::incomingConnection(qintptr socketDescriptor) { qDebug() << Q_FUNC_INFO << socketDescriptor; UserConnectThread *userConnectThread = new UserConnectThread(socketDescriptor, this); userConnectThread->start(); } void TcpServerMultithreading::parseMessage(const QString &message) { qDebug() << Q_FUNC_INFO << message; QWebSocket *pClient = qobject_cast<QWebSocket *>(sender()); pClient->sendTextMessage(QString("return: %1").arg(message)); } void TcpServerMultithreading::onNewConnection() { qDebug() << Q_FUNC_INFO; QWebSocket *m_pSocket = m_pWebSocketServer->nextPendingConnection(); connect(m_pSocket, &QWebSocket::textMessageReceived, this, &TcpServerMultithreading::parseMessage); }UserConnectThread.h
#ifndef USERCONNECTTHREAD_H #define USERCONNECTTHREAD_H #include <QObject> #include <QThread> #include <QTcpSocket> #include <QtWebSockets/QWebSocketServer> #include <QtWebSockets/QWebSocket> class UserConnectThread : public QThread { Q_OBJECT public: explicit UserConnectThread(int socketDescriptor, QObject *parent = nullptr); void run() override; signals: void sendToClient(QString message); public slots: void parseMessage(const QString &message); void onNewConnection(); private: int socketDescriptor; QWebSocketServer *m_pWebSocketServer; }; #endif // USERCONNECTTHREAD_HUserConnectThread.cpp
#include "UserConnectThread.h" UserConnectThread::UserConnectThread(int socketDescriptor, QObject *parent) : QThread{parent}, socketDescriptor(socketDescriptor) { } void UserConnectThread::run() { qDebug() << "Run Thread"; QTcpSocket *tcpSocket = new QTcpSocket(); if (!tcpSocket->setSocketDescriptor(socketDescriptor)) { //emit error(tcpSocket->error()); return; } m_pWebSocketServer = new QWebSocketServer(QStringLiteral("SSL Echo Server"), QWebSocketServer::NonSecureMode); connect(m_pWebSocketServer, &QWebSocketServer::newConnection, this, &UserConnectThread::onNewConnection); m_pWebSocketServer->handleConnection(tcpSocket); exec(); } void UserConnectThread::parseMessage(const QString &message) { qDebug() << Q_FUNC_INFO << message; QWebSocket *pClient = qobject_cast<QWebSocket *>(sender()); int sizeSend = pClient->sendTextMessage(QString("return: %1").arg(message)); qDebug() << Q_FUNC_INFO << "send: " << sizeSend; } void UserConnectThread::onNewConnection() { qDebug() << Q_FUNC_INFO; QWebSocket *m_pSocket = m_pWebSocketServer->nextPendingConnection(); connect(m_pSocket, &QWebSocket::textMessageReceived, this, &UserConnectThread::parseMessage); connect(this, &UserConnectThread::sendToClient, m_pSocket, &QWebSocket::sendTextMessage); }@red_spider said in QWebSocketServer and QThread:
connect(m_pWebSocketServer, &QWebSocketServer::newConnection,
this, &UserConnectThread::onNewConnection);Common error - since
thisis living in the main thread, the slot is executed there.
Ise the worker approach instead. But don't see why a thread is needed here at all though. -
@red_spider said in QWebSocketServer and QThread:
connect(m_pWebSocketServer, &QWebSocketServer::newConnection,
this, &UserConnectThread::onNewConnection);Common error - since
thisis living in the main thread, the slot is executed there.
Ise the worker approach instead. But don't see why a thread is needed here at all though.@Christian-Ehrlicher thank you for your reply, it will solve my problem there.
distribution into separate streams, it is necessary because when you download a large stream of binary data through a socket, everyone else who has their own sockets does not receive a response, they wait until the data is loaded
-
R red_spider has marked this topic as solved on