Как закрыть QWebSocket в потоке? - PullRequest
0 голосов
/ 05 марта 2019

Я перемещаю QWebSocket в поток, а затем как его закрыть в главном потоке?

Поскольку я перемещаю его в рабочий поток, я не могу напрямую вызвать close из основного потока.Вылетает с этим сообщением

QSocketNotifier: Уведомления сокетов не могут быть включены или отключены из другого потока

Без многопоточности это работает нормально.

Здесьмой кодЕсть идеи?Большое спасибо!

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QWebSocket>
#include <QThread>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
        Q_OBJECT

    public:
        explicit MainWindow(QWidget *parent = nullptr);
        ~MainWindow();

    private slots:
        void on_connectButton_clicked();
        void on_disconnectButton_clicked();

        void onClientConnected();
        void onClientClosed();
        void onClientTextMsg(const QString &msg);

    private:
        Ui::MainWindow *ui;
        QWebSocket *mClient;
        QThread mWorkerThread;
};

#endif // MAINWINDOW_H
#include "MainWindow.h"
#include "ui_MainWindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow),
    mClient(nullptr)
{
    ui->setupUi(this);

    mWorkerThread.start();

    qRegisterMetaType<QAbstractSocket::SocketState>();
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_connectButton_clicked()
{
    mClient = new QWebSocket();
    connect(mClient, &QWebSocket::connected, this, &MainWindow::onClientConnected, Qt::DirectConnection);
    connect(mClient, &QWebSocket::disconnected, this, &MainWindow::onClientClosed, Qt::DirectConnection);
    connect(mClient, &QWebSocket::textMessageReceived, this, &MainWindow::onClientTextMsg, Qt::DirectConnection);
    mClient->open(QUrl("ws://192.168.2.2:1936"));
    mClient->moveToThread(&mWorkerThread);
}

void MainWindow::on_disconnectButton_clicked()
{
    // FIXME crash
    // QSocketNotifier: Socket notifiers cannot be enabled or disabled from another thread
    mClient->close();
}

void MainWindow::onClientConnected() {
    qDebug() << "ws client connected";
}

void MainWindow::onClientClosed() {
    qDebug() << "ws client closed, " << mClient->closeReason() << mClient->errorString();
}

void MainWindow::onClientTextMsg(const QString &msg) {
    qDebug() << "ws recv msg:" << msg;
}

1 Ответ

0 голосов
/ 05 марта 2019

Использование QMetaObject::invokeMethod:

QMetaObject::invokeMethod(mClient, "close", Qt::QueuedConnection);
...