PostgreSQL 通过 LISTEN
和 NOTIFY
命令提供异步通知。客户端会话使用 LISTEN
命令注册其对特定通知频道的兴趣(并可以使用 UNLISTEN
命令停止监听)。当任何会话执行带有特定频道名称的 NOTIFY
命令时,所有在该频道上监听的会话都将收到异步通知。可以通过 “payload” 字符串来传递附加数据给监听者。
libpq 应用程序将 LISTEN
、UNLISTEN
和 NOTIFY
命令作为普通 SQL 命令提交。稍后可以通过调用 PQnotifies
来检测到 NOTIFY
消息的到达。
函数 PQnotifies
返回从服务器接收到的未处理通知消息列表中的下一个通知。如果没有待处理通知,则返回一个空指针。一旦从 PQnotifies
返回一个通知,它就被视为已处理,并将从通知列表中移除。
PGnotify *PQnotifies(PGconn *conn); typedef struct pgNotify { char *relname; /* notification channel name */ int be_pid; /* process ID of notifying server process */ char *extra; /* notification payload string */ } PGnotify;
在处理由 PQnotifies
返回的 PGnotify
对象后,请务必使用 PQfreemem
来释放它。释放 PGnotify
指针就足够了;relname
和 extra
字段不代表单独的分配。(这些字段的名称是历史遗留的;特别是,频道名称不一定与关系名称有关。)
示例 32.2 提供了一个演示异步通知用法的示例程序。
PQnotifies
实际上并不从服务器读取数据;它只是返回之前由另一个 libpq 函数吸收的消息。在 libpq 的早期版本中,确保及时接收 NOTIFY
消息的唯一方法是不断提交命令,即使是空的命令,然后在每次 PQexec
调用后检查 PQnotifies
。虽然这仍然有效,但由于浪费了处理能力,因此已被弃用。
当没有有用的命令要执行时,检查 NOTIFY
消息的更好方法是调用 PQconsumeInput
,然后检查 PQnotifies
。您可以使用 select()
来等待服务器上的数据到达,从而不使用CPU资源,除非有事情要做。(要获取与 select()
一起使用的文件描述符编号,请参见 PQsocket
。)请注意,无论您是使用 PQsendQuery
/PQgetResult
提交命令还是仅使用 PQexec
,这都可以正常工作。但是,您应该记住在每次 PQgetResult
或 PQexec
调用后检查 PQnotifies
,以查看在处理命令期间是否收到了任何通知。
如果您在文档中发现任何不正确之处、与您对特定功能的实际体验不符或需要进一步澄清的内容,请使用 此表单 报告文档问题。