<productname>PostgreSQL</productname> offers asynchronous notification
via the <command>LISTEN</command> and <command>NOTIFY</command>
commands. A client session registers its interest in a particular
notification channel with the <command>LISTEN</command> command (and
can stop listening with the <command>UNLISTEN</command> command). All
sessions listening on a particular channel will be notified
asynchronously when a <command>NOTIFY</command> command with that
channel name is executed by any session. A <quote>payload</quote> string can
be passed to communicate additional data to the listeners.
PostgreSQLは、LISTEN
とNOTIFY
コマンドを使用した、非同期通知をサポートします。
クライアントセッションは、LISTEN
コマンドを使用して処理対象とする特定の通知チャネルを登録します。
(通知監視を取り止めるにはUNLISTEN
コマンドを使用します。)
任意のセッションでそのチャネル名によるNOTIFY
コマンドが実行されると、特定チャネルを監視しているすべてのセッションは非同期に通知を受け取ります。
監視者に追加データを通信するために「ペイロード」文字列を渡すことができます。
<application>libpq</application> applications submit
<command>LISTEN</command>, <command>UNLISTEN</command>,
and <command>NOTIFY</command> commands as
ordinary SQL commands. The arrival of <command>NOTIFY</command>
messages can subsequently be detected by calling
<function id="libpq-PQnotifies">PQnotifies</function>.<indexterm><primary>PQnotifies</primary></indexterm>
libpqアプリケーションは、通常のSQLによる問い合わせと同じようにLISTEN
、UNLISTEN
およびNOTIFY
コマンドを発行することができます。
NOTIFY
メッセージの到着は、続いてPQnotifies
.を呼び出せば検出できます。
The function <function>PQnotifies</function> returns the next notification
from a list of unhandled notification messages received from the server.
It returns a null pointer if there are no pending notifications. Once a
notification is returned from <function>PQnotifies</function>, it is considered
handled and will be removed from the list of notifications.
PQnotifies
関数は、サーバから受信した通知メッセージの未処理リストから次の通知を返します。
保留中の通知がなくなればNULLポインタを返します。
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 */
char *relname; /* 通知チャネル名 */
int be_pid; /* 通知元サーバプロセスのプロセスID */
char *extra; /* 通知ペイロード文字列 */
} PGnotify;
After processing a <structname>PGnotify</structname> object returned
by <function>PQnotifies</function>, be sure to free it with
<xref linkend="libpq-PQfreemem"/>. It is sufficient to free the
<structname>PGnotify</structname> pointer; the
<structfield>relname</structfield> and <structfield>extra</structfield>
fields do not represent separate allocations. (The names of these fields
are historical; in particular, channel names need not have anything to
do with relation names.)
PQnotifies
で返されたPGnotify
オブジェクトの処理が終わったら、PQfreemem
を使用して確実に解放してください。
PGnotify
ポインタを解放することは重要です。
relname
とextra
フィールドは別の割り当てを表していません。
(これらのフィールド名は歴史的なものです。特にチャネル名はリレーション名と関係するものである必要はありません。)
<xref linkend="libpq-example-2"/> gives a sample program that illustrates the use of asynchronous notification. 例 32.2で非同期通知を使用したサンプルプログラムを示しています。
<function>PQnotifies</function> does not actually read data from the
server; it just returns messages previously absorbed by another
<application>libpq</application> function. In ancient releases of
<application>libpq</application>, the only way to ensure timely receipt
of <command>NOTIFY</command> messages was to constantly submit commands, even
empty ones, and then check <function>PQnotifies</function> after each
<xref linkend="libpq-PQexec"/>. While this still works, it is deprecated
as a waste of processing power.
PQnotifies
は実際にサーバのデータを読み出すわけではありません。
これは単に、他のlibpq関数が吸収してしまっていた通知メッセージを返すだけです。
libpqの古いリリースでは、NOTIFY
メッセージを適切な時点で確実に受け取るには、空の問い合わせでも何でも、とにかく一定時間ごとに問い合わせを送り、そしてPQexec
を実行するたびにPQnotifies
を検査するしかありませんでした。
今でもこの方法は動作しますが、処理能力の無駄使いをすることになるのでやめておくべきでしょう。
A better way to check for <command>NOTIFY</command> messages when you have no
useful commands to execute is to call
<xref linkend="libpq-PQconsumeInput"/>, then check
<function>PQnotifies</function>. You can use
<function>select()</function> to wait for data to arrive from the
server, thereby using no <acronym>CPU</acronym> power unless there is
something to do. (See <xref linkend="libpq-PQsocket"/> to obtain the file
descriptor number to use with <function>select()</function>.) Note that
this will work OK whether you submit commands with
<xref linkend="libpq-PQsendQuery"/>/<xref linkend="libpq-PQgetResult"/> or
simply use <xref linkend="libpq-PQexec"/>. You should, however, remember
to check <function>PQnotifies</function> after each
<xref linkend="libpq-PQgetResult"/> or <xref linkend="libpq-PQexec"/>, to
see if any notifications came in during the processing of the command.
実行すべき問い合わせがない時にNOTIFY
メッセージを検査するよい方法は、まずPQconsumeInput
を呼び出し、それからPQnotifies
を検査することです。
サーバからのデータの到着をselect()
で待つことができ、不必要な動作でCPUパワーを消費してしまうことがありません。
(select()
で使用するファイル記述子番号の取得については、PQsocket
を参照してください。)
なお、これは問い合わせにPQsendQuery
とPQgetResult
を使った時でも、またはおなじみのPQexec
を使った時でも動作します。
しかし通知がコマンドの処理中に届いていないかどうか、PQgetResult
あるいはPQexec
の実行ごとにPQnotifies
を調べることを忘れないようにしておくべきです。