我正在增强ROS(机器人操作系统)堆栈sql_database,以便能够处理postgresqls LISTEN和NOTIFY命令。如上所述,我在C ++程序中使用Ubuntu12.04上的libpq版本9.1.10-0。 但由于某些原因,我无法检索到NOTIFY。
我知道,有一个例子(例28-2。libpq示例程序2)并且它工作得很好。我玩了很长时间,并尝试尽可能准确地将其复制到我的代码中,并以某种方式更改示例代码,使其更类似于我遇到问题的代码。但这对我的问题没有帮助。
我可以在示例程序和手动登录数据库中收到通知,但不能在我想要使用的代码中收到通知。
我还尝试了什么:
COMMIT;
命令后执行LISTEN <channel>;
。但由于我没有公开交易,这导致了预期的警告。PQconsumeInput(connection_);
之前检查连接是否已经死亡 - 它是纯粹的活着始终使用NOTIFY <channel>;
这里也可以看到代码on github(在不稳定的分支上):
类PostgresqlDatabase(在sql_interface-&gt; database_interface-&gt; github上的src)
该类保存连接PGconn并提供
bool listenToChannel(std::string channel);
该类的主要目的是抽象sql查询,以便ROS程序员不再需要关心它们。
class databaseBinding
它是ROS和数据库功能之间的粘合剂。它包含一个PostgresqlDatabase对象,用于获取数据库连接并调用任务。
主要功能
做以下事情
PostgresqlDatabase::listenToChannel(std::string channel)
- 函数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;
}
答案 0 :(得分:3)
事实证明,连接有问题。 它是用该代码创建的:
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”数据库中发送任何通知并且连接良好。
对我来说,这是多么尴尬和不幸的行为。