gpt4 book ai didi

c++ - Qt QWebsocket::open block 用户界面

转载 作者:行者123 更新时间:2023-11-28 04:29:06 30 4
gpt4 key购买 nike

我正在开发一个小型系统,它由多个客户和一个管理应用程序组成。每个客户端都有一个 QWebSocket 服务器来监听管理员的请求,因此管理员应用程序需要连接到不同的客户端。

这是我的登录对话框:

Login dialog

登录前,我不知道哪个是客户端 IP 地址,所以每次我发送登录凭据时,我都需要尝试打开到该 IP 地址的连接。问题是在 Windows UI 中会阻塞,直到套接字服务器响应或超时,但在 Windows 中它工作正常。

编辑 1: 我关注了 Tung Le Thanh建议,因此代码包含他的提示。现在的主要问题是 ConnectionHelper 不能发出任何信号而不得到 QSocketNotifier: Socket notifiers cannot be enabled or disabled from another thread

我有一个 ConnectionHelper 负责向 WebSocket setver 发送接收数据。

主要.cpp

ConnectionHelper *helper = new ConnectionHelper();
LoginDialog dialog(helper);

QThread* thread = new QThread();
helper->moveToThread(thread);
thread->start();

dialog.show();
return a.exec();

LoginDialog 的构造函数:

connect(helper, &ConnectionHelper::onConnectionError, this, &LoginDialog::onCxnError);
connect(helper, &ConnectionHelper::loginInformationReceived, this, &LoginDialog::onLoginInfo);
connect(helper, &ConnectionHelper::cxnEstablished, this, &LoginDialog::onConnected);

接受插槽:

void LoginDialog::on_buttonBox_accepted()
{
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
QString host = ui->lineEditServer->text();
QString port = ui->lineEditPort->text();
QString ws = "ws://" + host + ":" + port;
helper->setUrl(QUrl(ws));
}

void ConnectionHelper::setUrl(QUrl url)
{
if(!webSocket)
{
webSocket = new QWebSocket();

connect(webSocket, &QWebSocket::textMessageReceived, this, &ConnectionHelper::processTextMessage, Qt::QueuedConnection);
connect(webSocket, &QWebSocket::binaryMessageReceived, this, &ConnectionHelper::processBinaryMessage);
connect(webSocket, &QWebSocket::disconnected , this, &ConnectionHelper::socketDisconnected);

connect(webSocket, QOverload<QAbstractSocket::SocketError>::of(&QWebSocket::error)
, this, [this](QAbstractSocket::SocketError error){
Q_UNUSED(error)
emit onConnectionError();
});

connect(webSocket, &QWebSocket::connected, this, [=]() {
emit cxnEstablished();
});

}
webSocket->open(url);
webSocket->open(url);
}

void ConnectionHelper::processTextMessage(QString message)
{
QJsonDocument response = QJsonDocument::fromJson(message.toUtf8());
QJsonObject objResponse = response.object();

QString action = objResponse[ACTION_KEY].toString();

if (action == ACTION_LOGIN)
emit loginInformationReceived(objResponse);
}

我会禁用 OK 按钮,直到收到任何响应并且在 Linux 上工作正常,但在 Windows 中整个 UI block 并变得无响应,直到收到响应。

我也尝试将 ConnectionHelper 实例移动到另一个线程,但我得到了这个响应:QSocketNotifier: Socket notifiers cannot be enabled or disabled from another thread

我没有想法,我需要找到一种方法来使 webSocket->open(url) 异步或类似的东西。

谢谢。

最佳答案

我意识到 QWebSocket::open 它是我使用的唯一异步函数。所以我只需要在设置 URL 和打开套接字连接之前有两个线程。

按照 Tung Le Thanh 的回答和一个小技巧,现在一切正常。我的解决方案是在连接打开并开始发出信号后恢复默认威胁。

void ConnectionHelper::setUrl(QUrl url, QThread* thread)
{
if(!webSocket)
{
webSocket = new QWebSocket();
connect(webSocket, &QWebSocket::connected, this, [this, thread]() {
this->moveToThread(thread);
webSocket->moveToThread(thread);

emit this->cxnEstablished();
});

}
webSocket->open(url);
}

现在 LoginDialog 需要发送它的 Thread

void LoginDialog::on_buttonBox_accepted()
{
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
QString host = ui->lineEditServer->text();
QString port = ui->lineEditPort->text();
QString ws = "ws://" + host + ":" + port;
QMetaObject::invokeMethod( helper, "setUrl", Qt::QueueConnection,
Q_ARG( QUrl, QUrl(ws)),
Q_ARG( QThread*, QThread::currentThread())
);
}

关于c++ - Qt QWebsocket::open block 用户界面,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53433554/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com