gpt4 book ai didi

c++ - 不在 C++ 程序中使用 libpq 检索 NOTIFY

转载 作者:太空狗 更新时间:2023-10-29 21:22:29 25 4
gpt4 key购买 nike

我正在增强 ROS(机器人操作系统)堆栈 sql_database能够处理 postgresqls LISTEN 和 NOTIFY 命令。如前所述,我在 C++ 程序中的 Ubuntu12.04 上使用 libpq 版本 9.1.10-0。但由于某些原因,我无法检索通知。

我知道,有一个示例(示例 28-2.libpq 示例程序 2)并且运行良好。我已经玩了很长时间,还尝试尽可能准确地将它复制到我的代码中,并以某种方式更改示例代码,使其更类似于我遇到问题的代码。但这对我的问题没有帮助。

我可以在示例程序和手动登录数据库时收到通知,但在我想使用的代码中却收不到。

我还尝试了什么:

  • 连接到不同的数据库 - 没有任何改变。
  • 正在做 COMMIT;在我执行了 LISTEN <channel>; 之后命令。但这导致了预期的警告,因为我没有未结交易。
  • 在我做之前检查连接是否断开PQconsumeInput(connection_); - 它纯粹是活的
  • 在同一函数中执行 LISTEN 命令,我在其中检查 NOTIFY(使用断点在两者之间触发 NOTIFY)- 没有改变任何东西。

NOTIFY 始终由 NOTIFY <channel>; 手动触发

代码结构

代码也可以在这里看到on github (在不稳定的分支上):

  • 类 PostgresqlDatabase(在 github 上的 sql_interface->database_interface->src 中)
    这个类持有连接 PGconn 并提供类似的任务

     bool listenToChannel(std::string channel);

    该类的主要目的是抽象 sql 查询,这样 ROS 程序员就不必再关心它们了。

  • 类数据库绑定(bind)
    它是 ROS 和数据库功能之间的粘合剂。它包含一个 PostgresqlDatabase 对象以获取数据库连接和调用任务。

  • 主要功能
    做以下事情

    1. 做一些 ROS 初始化工作
    2. 创建一个 databaseBinding 对象,它将初始化一个 PostgresqlDatabase 对象,该对象建立到我的数据库的连接
    3. 调用PostgresqlDatabase::listenToChannel(std::string channel) -功能
    4. 循环使用 PostgresqlDatabase::checkNotify(notification &no) 定期检查 NOTIFY -功能

一些代码

检查通知

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;
}
}

收听 channel

/*! 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;
}

最佳答案

事实证明,连接有问题。它是用该代码创建的:

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”数据库中收到任何通知并且连接良好。

对我来说,这是多么尴尬和不幸的行为。

关于c++ - 不在 C++ 程序中使用 libpq 检索 NOTIFY,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20495210/

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