Russian Qt Forum
Ноябрь 24, 2024, 05:58 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Проверка включения сервера  (Прочитано 12056 раз)
Примерный ученик
Бывалый
*****
Offline Offline

Сообщений: 450


И это не всегда помогает


Просмотр профиля
« : Октябрь 26, 2009, 12:42 »

Есть клиент, который общается с множеством баз PostgreSQL.
Как можно узнать, включен ли каждый из серверов?
При выполнении команды

QSqlDatabase testPSQL->open()

если база отключена, требуется прорва времени.
Есть ли другой способ?

QT 3.3.3
Записан

Как мало времени и как много нужно узнать
NicK
Гость
« Ответ #1 : Октябрь 26, 2009, 13:06 »

Код:
bool PING(QString strServer){
        QStringList strlstPingResults;
        bool boolRESULT=false;

        QStringList arguments;
        #ifdef Q_WS_WIN
            QTextCodec::setCodecForCStrings(QTextCodec::codecForName("cp-866"));
            arguments<<strServer;
        #endif
        #ifdef Q_WS_X11
            arguments<<strServer<<"-c 1";
        #endif


        QProcess myProcess;
        myProcess.start("ping", arguments);

        myProcess.waitForFinished(500);
        strlstPingResults<<myProcess.readAll();
        myProcess.deleteLater();

        for (int i=0;i<=strlstPingResults.count()-1;i++){
            qDebug()<<"DEBUG: core: ping results"<<strlstPingResults[i];
            boolRESULT=strlstPingResults[i].contains("ttl",Qt::CaseInsensitive);
            if (boolRESULT)break;
        };

        return boolRESULT;
}
Записан
BRE
Гость
« Ответ #2 : Октябрь 26, 2009, 13:19 »

При пинговании можно определить что компьютер в сети, но на нем может быть не запущен сервер PostgreSQL.

Можно попробовать подключиться используя QSocket к нужному хосту по нужному порту. Если подключение произойдет, можно считать что сервер PostgreSQL активен.
Записан
Примерный ученик
Бывалый
*****
Offline Offline

Сообщений: 450


И это не всегда помогает


Просмотр профиля
« Ответ #3 : Октябрь 26, 2009, 13:25 »

BRE  т.е. приконнектится? Попробую...
Записан

Как мало времени и как много нужно узнать
Примерный ученик
Бывалый
*****
Offline Offline

Сообщений: 450


И это не всегда помогает


Просмотр профиля
« Ответ #4 : Октябрь 26, 2009, 14:33 »

Кажись работает. Ед. вопрос, как долго ждать подключения?
Сделал
Код:
		QSocket test;
test.connectToHost(sql.value(1).toString(),sql.value(2).toInt());
int ii=0;
while(test.state()!=QSocket::Connected)
{
ii++;
if (ii==10) break;
qApp->processEvents();
}
if (test.state()==QSocket::Connected)
{
test.disconnect();
QMessageBox::critical( this,"","Есть связь");
}
else
{
QMessageBox::critical( this,"","Нет связи");
}
Десяти прерываний для местных серверов достаточно. А для удаленных?
Записан

Как мало времени и как много нужно узнать
BRE
Гость
« Ответ #5 : Октябрь 26, 2009, 15:04 »

Кажись работает. Ед. вопрос, как долго ждать подключения?

Десяти прерываний для местных серверов достаточно. А для удаленных?
Жди пока не подключишься или пока не произойдет ошибка.
Записан
Примерный ученик
Бывалый
*****
Offline Offline

Сообщений: 450


И это не всегда помогает


Просмотр профиля
« Ответ #6 : Октябрь 26, 2009, 15:41 »

Т.е ждать сигнала

void connected ()

или

void error ( int )

Непонимающий
Записан

Как мало времени и как много нужно узнать
BRE
Гость
« Ответ #7 : Октябрь 26, 2009, 15:54 »

Т.е ждать сигнала
void connected ()
или
void error ( int )
Непонимающий
Ну в общем да.
Посмотри как меняются состояния сокета, когда подключение удается и когда нет. Для того что бы решить доступен сервер или нет.
Записан
NicK
Гость
« Ответ #8 : Октябрь 26, 2009, 16:28 »

Пробовал так:
Код:
bool MainWindow::CheckConnection()
    {
            bool boolConnected=false;

            QProgressDialog *conect2hostDialog = new QProgressDialog("Waiting for connection...", "Cancel", 0, 0);
            conect2hostDialog->setModal(true);
            conect2hostDialog->show();
            //--------------------------------------------------------

            QTcpSocket test;
            test.connectToHost(strHostName,strPort.toInt());

            while(test.state()!=QTcpSocket::ConnectedState){
                if (conect2hostDialog->wasCanceled()){boolConnected=false;break;};
                qApp->processEvents();
            };

            if (test.state()==QTcpSocket::ConnectedState){
                boolConnected=true;
                test.disconnect();
                //QMessageBox::critical( this,"",tr("Connection established"));
            }
            else QMessageBox::critical( this,"",tr("Connection to ")+strHostName+":"+strPort+tr(" is failed."));
            //--------------------------------------------------------
            delete conect2hostDialog;

            return boolConnected;
}

Но, после нескольких неудачных попыток MySQL отвечает:
Цитировать
Database open error.

Host 'fedora' is blocked because of many connection errors; unblock with 'mysqladmin flush-hosts' QMYSQL: Unable to connect
MySQL считает мои проверки за ошибки подключения. Что я не так делаю?
« Последнее редактирование: Октябрь 26, 2009, 16:40 от NicK » Записан
BRE
Гость
« Ответ #9 : Октябрь 26, 2009, 16:57 »

Код
C++ (Qt)
#include <QCoreApplication>
#include <QTcpSocket>
#include <QDebug>
 
int main( int argc, char *argv[] )
{
       QCoreApplication app( argc, argv );
 
       QTcpSocket socket;
       socket.connectToHost( "localhost", 3306 );
       if( socket.waitForConnected() )
       {
               qDebug() << "MySql server active";
       }
       else
       {
               qDebug() << "MySql server not active";
       }
 
       return 0;
}
 
Записан
NicK
Гость
« Ответ #10 : Октябрь 26, 2009, 18:42 »

Для периодической проверки сервера по таймеру этот вариант не подходит.  Грустный
Как убедить MySQL что такие проверки не "connection eror"?
Записан
BRE
Гость
« Ответ #11 : Октябрь 26, 2009, 19:34 »

Для периодической проверки сервера по таймеру этот вариант не подходит.  Грустный
Как убедить MySQL что такие проверки не "connection eror"?
disconnect делать не забываешь?
Как часто пытаешься подключаться?

По хорошему нужно посмотреть протокол обмена сервера и клиента mysql.
Записан
Примерный ученик
Бывалый
*****
Offline Offline

Сообщений: 450


И это не всегда помогает


Просмотр профиля
« Ответ #12 : Октябрь 26, 2009, 21:36 »

Шпинял в течении часа. PostgresSQL не ругался...
Опрос через каждые 5 сек
Код:
	if (flagTestUsel) return;  // Идет обработка
flagTestUsel=true; // начинаем работу
QSqlQuery sql(MyPSQL); // наша база
sql.exec("SELECT * FROM usel");
int prz=0;
while (sql.next()) // проверка всех серверов
{
QSocket test;
test.connectToHost(sql.value(1).toString(),sql.value(2).toInt());
int ii=0;
while(test.state()!=QSocket::Connected)
{
ii++;
if (ii==10) break;
qApp->processEvents();
}
if (test.state()==QSocket::Connected)
{
prz=1; // есть связь
test.disconnect();
}
else
{
prz=0; // нет связи
}
if (prz!=sql.value(5).toString()) // статус изменился
{
QSqlCursor sCur("usel",true,MyPSQL);
sCur.select("ind="+sql.value(7).toString());
if (sCur.next())
{
QSqlRecord *buffer;
buffer = sCur.primeUpdate();  // запись для обновления
buffer->setValue("prz",prz);
sCur.update();
}
qApp->processEvents();
}
}
textLabel1->setText("Контроль серверов. Пауза в работе");
flagTestUsel=false; // закончили проверку

В логе только сообщения типа

2009-10-26 13:51:58 LOG:  incomplete startup packet
« Последнее редактирование: Октябрь 26, 2009, 21:39 от Примерный ученик » Записан

Как мало времени и как много нужно узнать
Примерный ученик
Бывалый
*****
Offline Offline

Сообщений: 450


И это не всегда помогает


Просмотр профиля
« Ответ #13 : Октябрь 26, 2009, 21:40 »

Но обмен проходил нормально

А

QTcpSocket socket;

в QT3 не присутствует Смеющийся
Записан

Как мало времени и как много нужно узнать
NicK
Гость
« Ответ #14 : Октябрь 26, 2009, 23:32 »

В течение 15-20 минут по таймеру каждые 15 секунд запускается проверка сервера:
Код
C++ (Qt)
bool CheckConnection()
{
           bool boolConnected=false;
 
           QTcpSocket test;
           test.connectToHost(strCONNECTION_SETTINGS_Hostname,strCONNECTION_SETTINGS_Port.toInt());
           qDebug()<<"DEBUG: core: polling server...";
           if( test.waitForConnected() ){
               boolConnected=true;
               qDebug()<<"DEBUG: core: connection established";
               qDebug()<<"DEBUG: core: disconnecting...";
               test.waitForDisconnected();
               qDebug()<<"DEBUG: core: disconnected";
           }
           else {
               boolConnected=false;
               qDebug()<<"DEBUG: core: connection failed";
           };
 
           return boolConnected;
}

Все отлично работает. Удачный коннект и разъединение. Но если через эти 15-20 минут попробовать это:
Код
C++ (Qt)
 {
QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL","mysql_db_core");
       qDebug()<<"DEBUG: core: create connection";
       db.setHostName(strCONNECTION_SETTINGS_Hostname);
       db.setPort(strCONNECTION_SETTINGS_Port.toInt());
       db.setDatabaseName(strCONNECTION_SETTINGS_DBname);
       db.setUserName(strCONNECTION_SETTINGS_Username);
       db.setPassword(strCONNECTION_SETTINGS_Password);
if (boolCONNECTION_SETTINGS_SSL) db.setConnectOptions("CLIENT_SSL=1;CLIENT_IGNORE_SPACE=1"); // use an SSL connection to the server
if (db.open()){
 
...
 
   db.close();
};
 
 };
 qDebug()<<"DEBUG: core: remove connection.";QSqlDatabase::removeDatabase("mysql_db_core");

то на вызове if (db.open()) получаю все то же сообщение о блокировании соединения.
Сами же проверки выполняются и дальше нормально, но базу уже не открыть.


Qt - 4.5.2
ОС- KUbuntu 9.04

Сервер - CentOS release 5.4 (Final) 2.6.18-164.2.1.el5.plus
MySQL - mysql  Ver 14.12 Distrib 5.0.77, for redhat-linux-gnu (i686) using readline 5.1

« Последнее редактирование: Октябрь 26, 2009, 23:39 от NicK » Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.204 секунд. Запросов: 23.