?
This document uses PHP Chinese website manual Release
PostgreSQL通過LISTEN和NOTIFY命令提供對異步通知的支持。 一個(gè)服務(wù)器用LISTEN命令注冊一個(gè)它感興趣的通知條件(也可以用UNLISTENcommand)命令停止監(jiān)聽)。 所有正在監(jiān)聽某一通知條件的會(huì)話在該條件名的NOTIFY(通知)被任何會(huì)話執(zhí) 行后都將被異步地通知。通知發(fā)出者不會(huì)傳遞附加的信息到監(jiān)聽者。因此,很典型地是 ,任何實(shí)際的需要被傳遞的數(shù)據(jù)都是通過一個(gè)數(shù)據(jù)庫表傳遞的。通常,條件名與相關(guān)聯(lián)的表同名, 但是并不是一定要與某個(gè)表相關(guān)才行。一個(gè)"payload"可以向聽眾傳達(dá)額外的數(shù)據(jù)。
libpq應(yīng)用把LISTEN,UNLISTEN
和NOTIFY命令作為通常的 SQL 命令提交。
隨后通過調(diào)用,PQnotifies
可以偵測到NOTIFY消息的到達(dá)。
函數(shù)PQnotifies
從一個(gè)來自服務(wù)器的未處理的通知信息列表中返回下一條通知。
如果沒有未處理的信息則返回 NULL 指針。一旦PQnotifies
返回一條通知,
該通知會(huì)被認(rèn)為已處理并且將被從通知列表中刪除。
PGnotify *PQnotifies(PGconn *conn); typedef struct pgNotify { char *relname; /* notification channel name 通知名字*/ int be_pid; /* process ID of notifying server process 服務(wù)器進(jìn)程ID*/ char *extra; /* notification payload string 通知參數(shù)*/ } PGnotify;
在處理完PGnotify返回的PQnotifies
對象后,別忘了用PQfreemem
把它釋放,
以避免內(nèi)存泄漏。釋放PGnotify指針就足夠了;relname和extra字段并未代表獨(dú)立分配的內(nèi)存。
(這些領(lǐng)域的名稱是歷史性的,尤其是頻道名稱與名稱沒有什么關(guān)系。)
Example 31-2給出了一個(gè)使用異步通知的例子。
PQnotifies
實(shí)際上并不讀取服務(wù)器數(shù)據(jù);它只是返回被前面的另
一個(gè)libpq函數(shù)吸收的信息。在以前的libpq的版本里,周期性的收到NOTIFY信息
的唯一方法是持續(xù)的提交命令,即使是空查詢也可以,并且在每次PQexec
后檢查PQnotifies
。
現(xiàn)在這個(gè)方法也能還工作,不過我們認(rèn)為它太浪費(fèi)處理器時(shí)間而廢棄了它。
在你沒有可用的命令提交時(shí)檢查NOTIFY消息的更好的方法是調(diào)用PQconsumeInput
,
然后檢查PQnotifies
。你可以使用select()
來等待服務(wù)器數(shù)據(jù)的到達(dá),
這樣在沒有數(shù)據(jù)可處理時(shí)可以不浪費(fèi)CPU時(shí)間。(參閱PQsocket
獲取
用于select()
的文件描述符。)注意這種方法不管你使用PQsendQuery
/PQgetResult
還是簡單的PQexec
.來執(zhí)行命令都能工作。不過,你應(yīng)該記住在每次PQgetResult
或
PQexec后檢查PQexec
,看看在處理命令的過程中是否有通知到達(dá)。