база данных — не извлечение NOTIFY с помощью libpq в программе на C ++

Я улучшаю стек ROS (операционной системы робота) sql_database чтобы иметь возможность обрабатывать команды postgresqls LISTEN и NOTIFY. Как уже упоминалось, я использую libpq версии 9.1.10-0 на Ubuntu12.04 в программе на C ++.
Но по некоторым причинам я не могу получить УВЕДОМЛЕНИЕ.

Я знаю, что есть пример (Пример 28-2. Libpq Example Program 2), и он прекрасно работает. Я играл с ним довольно долго, а также пытался скопировать его в свой код как можно точнее и изменить пример кода таким образом, чтобы он был более похож на код, с которым у меня проблемы. Но это не помогло для моей проблемы.

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

Что еще я попробовал:

  • Подключение к другой базе данных — ничего не изменилось.
  • Делать COMMIT; после того, как я выполнил LISTEN <channel>; команда. Но это вызвало предупреждение, как и ожидалось, поскольку у меня не было открытой транзакции.
  • Проверьте, если связь не работает, прежде чем я PQconsumeInput(connection_); — это чисто живой
  • выполнить команду LISTEN в той же функции, где я проверяю NOTIFY (используя точку останова для запуска NOTIFY между ними) — ничего не изменилось.

УВЕДОМЛЕНИЕ всегда запускалось вручную с NOTIFY <channel>;

Код также можно увидеть здесь на GitHub (на нестабильных ветках):

  • класс PostgresqlDatabase (в sql_interface-> database_interface-> src на github)
    Этот класс содержит соединение PGconn и предоставляет такие задачи, как

     bool listenToChannel(std::string channel);
    

    Основная цель этого класса — абстрагирование запросов sql, чтобы ROS-программисты больше не заботились о них.

  • класс databaseBinding
    это клей между ROS и функциональностью базы данных. Он содержит объект PostgresqlDatabase для получения подключения к базе данных и для вызова задач.

  • Основная функция
    Делает следующие вещи

    1. сделать некоторые вещи инициализации ROS
    2. создайте объект databaseBinding, который будет инициализировать объект PostgresqlDatabase, который создает соединение с моей базой данных
    3. позвонить PostgresqlDatabase::listenToChannel(std::string channel)-функции
    4. Заходите в цикл, периодически проверяя УВЕДОМЛЕНИЕ, используя PostgresqlDatabase::checkNotify(notification &no)-функции

Проверка на УВЕДОМЛЕНИЕ

Функция checkNotify, которая запускается примерно 5 раз в секунду:

/*! Checks for a received NOTIFY and returns it. */
bool PostgresqlDatabase::checkNotify(notification &no)
{
PGnotify   *notify;
PQconsumeInput(connection_);
if ((notify = PQnotifies(connection_)) != NULL)
{
no.channel = notify->relname;
no.sending_pid = notify->be_pid;
no.payload = notify->extra;
PQfreemem(notify);
return true;
} else
{
no.channel = "";
no.sending_pid = 0;
no.payload = "";
PQfreemem(notify);
return false;
}
}

Прослушивание канала

/*! Listens to a specified channel using the Postgresql LISTEN-function.*/
bool PostgresqlDatabase::listenToChannel(std::string channel) {
//look, if we're already listening to the channel in our list
if (std::find(channels_.begin(),channels_.end(),channel) == channels_.end() )
{
std::string query = "LISTEN " + channel;
PGresultAutoPtr result = PQexec(connection_,query.c_str());
if (PQresultStatus(*result) != PGRES_COMMAND_OK)
{
ROS_WARN("LISTEN command failed: %s", PQerrorMessage(connection_));
return false;
}
ROS_INFO("Now listening to channel \"%s\"",channel.c_str());
channels_.push_back(channel);
return true;
}
ROS_INFO("We are already listening to channel \"%s\" - nothing to be done",channel.c_str());
return true;
}

2

Решение

Так что оказалось, что с соединением что-то не так.
Он был создан с этим кодом:

void PostgresqlDatabase::pgMDBconstruct(std::string host, std::string port,
std::string user, std::string password, std::string dbname )
{
std::string conn_info = "host=" + host + " port=" + port +
" user=" + user + " password=" + password + " dbname=" + dbname;
connection_= PQconnectdb(conn_info.c_str());
if (PQstatus(connection_)!=CONNECTION_OK)
{
ROS_ERROR("Database connection failed with error message: %s", PQerrorMessage(connection_));
}
}

С host=192.168.10.100, port=5432, user=turtlebot, password= , dbname=rosdb.
Но пустое имя пользователя не удовлетворяет использованию PQconnectdb, что по какой-то причине вызвало его вход в базу данных «turtlebot». К сожалению, эта база данных существовала на моем сервере. И, конечно же, он не получил никаких уведомлений в базе данных «rosdb» и имел хорошее соединение.

Какое для меня неловкое и неудачное поведение.

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]