我正在开发一个小型系统,它由几个客户和一个管理应用程序组成。每个客户端都有一个 QWebSocket 服务器来监听管理员的请求,因此管理员应用程序需要连接到不同的客户端。
这是我的登录对话框:
在登录之前,我不知道哪个是客户端 IP 地址,因此每次发送登录凭据时,我都需要尝试打开与该 IP 地址的连接。问题是在 Windows UI 中阻塞直到套接字服务器响应或超时,但在 Windows 中它工作正常。
编辑 1:我遵循了Tung Le Thanh的建议,因此代码中包含了他的提示。现在的主要问题是如果ConnectionHelper
没有获得QSocketNotifier 就无法发出任何信号:Socket notifiers cannot be enabled or disabled from another thread
我有一个ConnectionHelper
负责将接收数据发送到 WebSocket setver 和从 WebSocket setver 发送接收数据。
主文件
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);
}
我确实禁用“确定”按钮,直到收到任何响应并且在 Linux 上工作正常,但在 Windows 中,整个 UI 块并且在收到响应之前变得无响应。
我也尝试将ConnectionHelper
实例移动到另一个线程,但我得到了这个响应:QSocketNotifier: Socket notifiers cannot be enabled or disabled from another thread
我没有想法,我需要找到一种方法来进行webSocket->open(url)
异步或类似的事情。
谢谢。