Я работаю на небольшой системе, она сделана несколькими клиентами и одним приложением администратора.У каждого клиента есть сервер QWebSocket для прослушивания запросов администратора, поэтому приложение администратора должно подключаться к различным клиентам.
Это мой диалог входа в систему:
Перед входом яЯ не знаю, какой IP-адрес клиента, поэтому каждый раз, когда я отправляю учетные данные, мне нужно пытаться открыть соединение с этим IP-адресом.Проблема в том, что в блоках пользовательского интерфейса Windows до тех пор, пока сервер сокетов не ответит или тайм-аут не достигнут, но в Windows он работает нормально.
РЕДАКТ. 1: Я следовал Тун Ле Тхань предложениямпоэтому код включает в себя его советы.Теперь основная проблема заключается в том, что ConnectionHelper
не может излучать какой-либо сигнал без получения QSocketNotifier: уведомители сокетов не могут быть включены или отключены из другого потока
У меня есть ConnectionHelper
, который находится вПлата за отправку полученных данных в и из установщика WebSocket.
main.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);
}
Я отключаю кнопку ОК, пока не получим какой-либо ответ, и он отлично работает в Linux, но в Windows весь блок пользовательского интерфейса и перестает отвечать до получения ответа.
Я также пытаюсь переместитьсяConnectionHelper
экземпляр в другой поток, но я получил этот ответ: QSocketNotifier: Уведомления сокетов нельзя включить или отключить из другого потока
У меня нет идей, которые мне нужно найтиспособ сделать webSocket->open(url)
асинхронным или что-нибудь в этом роде.
Спасибо.