我已经设置了一个触发器,并使用pgadmin4(使用LISTEN)进行了测试,表的更改会得到通知。期望的是,一个Web界面可能会更改设置,我的后端代码必须拾取这些更改并应用。
我创建了一个小类(函数是内联的)来扩展通知接收器类。
class SettingsChangeListener: public pqxx::notification_receiver
{
public:
SettingsChangeListener(pqxx::connection_base &c);
virtual void operator()(const std::string &payload, int backend_pid)
throw ();
void RegisterParentData(SINT32 queueId, UINT32 eventID);
private:
SINT32 m_parentQueueHandle; // handle to the parent's message queue
UINT32 m_eventID; // event to send to the parent on notification
};
inline SettingsChangeListener::SettingsChangeListener(pqxx::connection_base &c)
: pqxx::notification_receiver(c, "settings_changed"), m_parentQueueHandle(0), m_eventID(0)
{
}
inline void SettingsChangeListener::operator()(const std::string &payload, int backend_pid)
throw ()
{
if (m_parentQueueHandle > 0)
{
LOG_SYSTEM_INFO("Detected Change in Settings\n");
// don't need the notification text - notify parent that the data has changed
CmnMessage msg;
msg.SetMessageID(m_eventID);
msg.SetMessageType(MESSAGE_TYPE_Local);
msg.SetMessageSource(MODULE_DATABASE);
MsgQueueMessage msgToSend;
size_t size = msg.Export(msgToSend);
if (FAIL == msgsnd(m_parentQueueHandle, &msgToSend, size, IPC_NOWAIT))
{
LOG_SYSTEM_ERROR("FAILED to send message on queue : %s\n", strerror(errno));
}
}
}
inline void SettingsChangeListener::RegisterParentData(SINT32 queueId, UINT32 eventID)
{
m_parentQueueHandle = msgget(queueId, IPC_CREAT | MSGQ_CREAT_PERMISSION);
m_eventID = eventID;
}
在我的另一个类中,我包含了SettingsChangeListener的一个成员,并在该类的构造函数中进行了初始化。
MyClass::MyClass()
: m_connection(DB_CONNECTION_STRING.c_str()), m_settingsDbAdapter(m_connection), m_settingsChangeListener(m_connection)
我的天
连接和成员在应用程序的持续时间内保持不变。DB适配器是一个管理设置表(添加/更新/删除/获取)的类,并且可以正常工作。
我在operator()()中放置了一个断点,它永远不会被命中,我永远不会看到通知。我设置了一个断点并确认父数据的注册按预期发生。
这是我第一次使用pqxx,并不是所有的函数看起来都很容易实现。我在想,有一些简单的东西我错过了,但我就是找不到它。
1条答案
按热度按时间nzrxty8p1#
我在示例代码中遗漏了一部分。这个功能应该存在于线程的上下文中,并且需要以下内容。这是从示例中逐字引用的。我将删除我不使用的部分。总的来说,pselect可能是让它工作的关键。