LINUX.ORG.RU

QxtWeb и HTTP-сервер в отдельном потоке

 , libqxt,


0

1

Пытаюсь заставить работать HTTP-сервер из QxtWeb в отдельном потоке — ничего не получается, поток начинает жрать целое ядро, на HTTP-запросы не отвечает.

Когда оно работает в основном потоке — всё отлично работает.

class HTTPServer : public QObject
{
    Q_OBJECT
public:
    HTTPServer(const HTTPServer&) = delete;
    HTTPServer operator=(const HTTPServer&) = delete;
    
    explicit HTTPServer(QObject *parent = 0);
    virtual ~HTTPServer();
    void responseCheckDonglesStatus(int status, const QString &message, int requestID);
private:
    QxtHttpServerConnector *m_Connector         = nullptr;
    QxtHttpSessionManager *m_Server             = nullptr;
    QxtWebServiceDirectory *m_RootService       = nullptr;
    ServiceChecker *m_ServiceChecker            = nullptr;

signals:
    void initError();
    void checkDonglesStatus(int requestID);
    void sigThreadPong();
    
public slots:
    void init();
    void onThreadPing();
private slots:
    void onCheckDonglesStatus(const int requestID);
}

HTTPServer::HTTPServer(QObject *parent) :
    QObject(parent)
{
    m_Connector = new QxtHttpServerConnector(this);
    m_Server = new QxtHttpSessionManager(this);
    m_Server->setConnector(m_Connector);
    m_RootService = new QxtWebServiceDirectory(m_Server, this);
    m_ServiceChecker = new ServiceChecker(m_Server, this);
    m_ServiceSendSms = new ServiceSendSms(m_Server, this);
    m_RootService->addService("check", m_ServiceChecker);
    m_Server->setStaticContentService(m_RootService);

    connect(m_ServiceChecker, SIGNAL(checkDonglesStatus(int)), SLOT(onCheckDonglesStatus(int)));
}

void HTTPServer::init()
{
    //FIXME: Qt5 - change to localhost
    m_Server->setListenInterface(QHostAddress::Any);
    m_Server->setPort(8000);
    if(!m_Server->start()) {
        Utils::logger(LogCritical, "HTTPServer: start failed");
        emit initError();
        return;
    }
    Utils::logger(LogInfo, "HTTPServer: start success");
}

void HTTPServer::onCheckDonglesStatus(const int requestID)
{
    emit checkDonglesStatus(requestID);
}

void HTTPServer::responseCheckDonglesStatus(int status, const QString &message, int requestID)
{
    m_ServiceChecker->responseDonglesStatus(status, message, requestID);
}

void HTTPServer::onThreadPing()
{
    emit sigThreadPong();
}
class ServiceChecker : public QxtWebServiceDirectory
{
    Q_OBJECT
public:
    explicit ServiceChecker(QxtAbstractWebSessionManager *sm, QObject *parent = 0);
    void pageRequestedEvent(QxtWebRequestEvent *event);
    void responseDonglesStatus(int status, const QString &message, int id);
signals:
    void checkDonglesStatus(int requestID);
};

ServiceChecker::ServiceChecker(QxtAbstractWebSessionManager *sm, QObject *parent) :
    QxtWebServiceDirectory(sm, parent)
{
}

void ServiceChecker::pageRequestedEvent(QxtWebRequestEvent *event)
{
    qDebug("ServiceChecker: request %s", qPrintable(event->method));
    if(event->method == "GET") {
        syslog(LOG_DEBUG, "SCGI URL %s", qPrintable(event->url.toString()));
        syslog(LOG_DEBUG, "SCGI ORIGINAL URL %s", qPrintable(event->originalUrl.toString()));
        syslog(LOG_DEBUG, "SCGI URL %s", qPrintable(event->url.path()));
        syslog(LOG_DEBUG, "SCGI ORIGINAL URL %s", qPrintable(event->originalUrl.path()));

        QString object = event->url.queryItemValue("object");
        if(object == "dongles")
            emit checkDonglesStatus(event->requestID);
    }
}


void ServiceChecker::responseDonglesStatus(int status, const QString &message, int id)
{
    QVariantMap m;
    m["status"] = status;
    m["message"] = message;
    QJson::Serializer s;
    QByteArray page = s.serialize(m);
    postEvent(new QxtWebPageEvent(0, id, page));
}

Собсно, запуск такой:

_httpServer = new HTTPServer;
_threadHTTPServer = new QThread(this);
_threadHTTPServer->setObjectName("HTTP Server");
_httpServer->moveToThread(_threadHTTPServer);

connect(this, SIGNAL(sigStartHTTPServer()), _httpServer, SLOT(init()));
connect(_httpServer, SIGNAL(initError()), SLOT(onInitError()));
connect(_httpServer, SIGNAL(checkDonglesStatus(int)), SLOT(onRestfulCheckDonglesStatus(int)));

_threadHTTPServer->start(); 
emit sigStartHTTPServer();

Я проверяю, вроде все объекты нормально создаются в другом потоке, и стартует сервер в другом потоке, но всё равно, просто не отвечает.

★★★★★

Последнее исправление: Chaser_Andrey (всего исправлений: 1)

в _threadHTTPServer разве не надо QEventLoop завести? (не работал с Qxt, пользуюсь Tufao - работает. В т.ч. можно и в поток обработку положить по желанию)

dib2 ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.