ピアツーピアチャットやソーシャルネットワーキングアプリなど、リアルタイムなクライアントサーバー通信に大きく依存するアプリケーションでは、ソケットイベントの送受信が急速に困難になる可能性があります。Sailsは、**Resourceful PubSub**(パブリッシュ/サブスクライブ)という概念を導入することで、ソケットイベントに関連する複雑さを軽減するのに役立ちます。アプリケーション内のすべてのモデルには、Resourceful PubSubメソッドが自動的に装備されており、個々のデータベースレコードに関する通知のブロードキャストとソケットの通知へのサブスクライブの両方に対して、従来のデータ中心インターフェースを提供します。
アプリケーションで現在ブループリントAPIを使用している場合、Resourceful PubSubメソッドも既に使用しています!これらは、Sailsにバンドルされたデフォルトのブループリントアクションに組み込まれており、これらのアクションの実行時に自動的に呼び出され、データがフェッチされると要求元のソケットがサブスクライブされ、データが変更されると、既にサブスクライブされているソケットにメッセージがブロードキャストされます。(ソケットは.subscribe()を呼び出すか、またはfindまたはfindOneブループリントへの以前のソケットリクエストによってサブスクライブできます。)
カスタムコードを作成する場合でも、sails.sockets.*メソッドを直接使用する代わりに、このセクションで説明されているメソッドを手動で呼び出すことができます。Resourceful PubSubメソッドは、アプリケーション全体のソケット通信のインターフェースを標準化する方法と考えてください。これらのインターフェース要素は、ルーム名、ソケットメッセージとして送信されるデータのスキーマ、またはソケットイベントの名前などです。これらのメソッドは、1つ以上のユーザーインターフェースがソケットイベントをリッスンしてバックエンドと同期を保つシナリオに限定して設計されています。それがユースケースに当てはまらない場合、または判断に迷う場合は、心配しないでください。sails.sockets.broadcast()、sails.sockets.join()、またはsails.sockets.leave()を直接呼び出してください。どちらのアプローチを使用するか、あるいは同じアプリケーションで両方のアプローチを使用することも完全に許容されます。
Sailsは、3つの異なるResourceful PubSub(RPS)メソッドを公開しています:.publish()、.subscribe()、および.unsubscribe()。
Resourceful PubSubメソッドをより深く理解するには、まず基礎となるsails.sockets.*メソッドに精通すると役立つ場合があります。これは、各RPSメソッドが、より単純なsails.sockets.*メソッドのコンテキスト化されたラッパーにすぎないためです。
.publish()はsails.sockets.broadcast()に似ています。.subscribe()はsails.sockets.join()に似ています。.unsubscribe()はsails.sockets.leave()に似ています。これらのメソッドとsails.sockets.*の対応物との最大の相違点は、RPSメソッドがより高レベルのインターフェースを公開することです。たとえば、RPSメソッドはバックグラウンドでルーム名を自動的に選択し、モデルのIDに基づいて従来のイベント名を推測します。
クライアントでソケットイベントをリッスンするために任意のJavaScriptライブラリを使用できますが、Sailsはsails.io.jsという独自のソケットクライアントを提供しており、Socket.IOをサポートするWebブラウザやNode.jsプロセスからSailsサーバーと簡単に通信できます。Sailsソケットクライアントを使用すると、Resourceful PubSubイベントのリッスンは次のようになります。
io.socket.on('<model identity>', function (msg) {
});
モデルIDは、モデルファイルで手動で設定されていない限り、通常はモデル名の小文字バージョンです。
アプリケーションに「name」属性を持つUserという名前のモデルがあるとします。まず、「user」イベントのリスナーを追加します。
io.socket.on('user', function(msg){
console.log(msg);
})
これにより、クライアントソケットが受信するすべての通知がコンソールに出力されます。ただし、このクライアントソケットを1つ以上の既存のUserレコードにサブスクライブするまで(サーバーサイドコードで)、これらのメッセージは実際には受信されません。
アプリケーションでブループリントAPIが有効になっている場合、クライアントソケットをUserレコードにサブスクライブするのは非常に簡単です。データのフェッチに加えて、"Find"ブループリントアクションがソケットリクエストを介してアクセスされた場合、User.subscribe()(Resourceful PubSubメソッド)が自動的に呼び出されます。
たとえば、https://:1337/userにソケットGETリクエストを送信するクライアントサイドコードを作成したとします。
io.socket.get('/user', function(resData) {
console.log(resData);
});
それが実行されると、「Find」ブループリントアクションがヒットし、Sailsサーバーから現在のユーザーリストが返されます。そして、通常のHTTPリクエスト(jQuery.get('/user')など)を送信した場合、それだけが実行されます。しかし、ソケットリクエストを送信したため、サーバーはまた、返されたユーザーレコードに関する今後の通知(.publish()への呼び出し)にクライアントソケットをサブスクライブしました。
仮想リクエストの送信に
sails.io.jsクライアントを使用する方法の詳細については、io.socket.get()を参照してください。
.subscribe()とは異なり、RPSの.publish()メソッドはどこからでも実行できます。ソケットリクエスト、AJAXリクエスト、またはコマンドラインからのcURLリクエストの結果としてトリガーされるコントローラーアクション、カスタムヘルパー、またはコマンドラインスクリプトなどです。
上記の例を続けると、追加のブラウザウィンドウを開いて次のURLにアクセスした場合
/user/create?name=joe
元のウィンドウのコンソールに次のようなものが表示されます。
{
verb: 'created',
id: 1,
data: {
id: 1,
name: 'joe',
createdAt: '2014-08-01T05:50:19.855Z'
updatedAt: '2014-08-01T05:50:19.855Z'
}
}
ここで見えているのは、"Create"ブループリントアクションによってブロードキャストされた辞書(別名プレーンなJavaScriptオブジェクト)です。ブループリントAPIの場合、このデータの形式は標準化されていますが、アプリケーションでは.publish()を使用して任意のデータをブロードキャストできます。