.subscribe()
1つ以上のデータベースレコードの変更/削除に対して要求クライアントソケットをサブスクライブします。
Something.subscribe(req, ids);
引数 | タイプ | 詳細 | |
---|---|---|---|
1 | req | サブスクライブするソケットを含む、受信ソケット要求 (req )。 |
|
2 | ids | レコード ID (主キー値) の配列。 |
クライアントソケットがレコードにサブスクライブされると、その動的「レコードルーム」のメンバーになります。つまり、.publish()
によってそのルームにブロードキャストされるすべてのメッセージを受信します。
サーバーで、コントローラーアクションで
// On the server:
if (!this.req.isSocket) {
throw {badRequest: 'Only a client socket can subscribe to Louies. But you look like an HTTP request to me.'};
}
// Let's say our client socket has a problem with people named "louie".
// First we'll find all users named "louie" (or "louis" even-- we should be thorough)
let usersNamedLouie = await User.find({ or: [{name: 'louie'},{name: 'louis'}] });
// Now we'll subscribe our client socket to each of these records.
User.subscribe(this.req, _.pluck(usersNamedLouie, 'id'));
// All done! We might send down some data, or just an empty 200 (OK) response.
次に、クライアント側コードに戻ります。
// On the client:
// Send a request to the "subscribeToLouies" action, subscribing this client socket
// to all future events that the server publishes about Louies.
io.socket.get('/foo/bar/subscribeToLouies', function (data, jwr){
if (jwr.error) {
console.error('Could not subscribe to Louie-related notifications: '+jwr.error);
return;
}
console.log('Successfully subscribed.');
});
これからは、要求クライアントソケットが接続されている限り、サーバー側コード (たとえば、他のアクションやヘルパー) が上でサブスクライブした Louie のいずれかに対して User.publish()
を呼び出すたびに通知を受信します。
クライアント側コードでこれらの今後の通知を処理するには、.on()
を使用して関連するイベントをリッスンする必要があります。たとえば
// On the client:
// Whenever a `user` event is received, say something.
io.socket.on('user', function(msg) {
console.log('Got a message about a Louie: ', msg);
});
Sails/Socket.IO のルームとイベントの違いに関する詳細については、コンセプト > リアルタイム を参照してください。
一部のアプリケーションでは、同じレコードに関連する 2 つの異なるチャンネルを管理する必要があります。これを実現するには、.getRoomName()
と sails.sockets.join()
を組み合わせることができます
// On the server, in your subscribe action…
if (!orgId) { throw 'badRequest'; }
if (!this.req.isSocket) { throw {badRequest: 'This action is designed for use with WebSockets.'}; }
let me = await User.findOne({
id: this.req.session.userId
})
.populate('globalAdminOfOrganizations');
// Subscribe to general notifications.
Organization.subscribe(this.req, orgId);
// If this user is a global admin of this organization, then also subscribe them to
// an additional private room (this is used for additional notifications intended only
// for global admins):
if (globalAdminOfOrganizations.includes(orgId)) {
let privateRoom = Organization.getRoomName(`${orgId}-admins-only`);
sails.sockets.join(this.req, privateRoom);
}
後で、これらのルームのいずれかに公開するには、適切なルーム名 (例: "13-admins-only") を計算して、sails.sockets.broadcast()
を使用して通知をブラストアウトします。
req
を渡して要求しているソケットを参照する前に、req.isSocket === true
を確認してください。指定されたreq
は、任意の古い HTTP 要求ではなく、ソケット要求からのものでなければなりません。.subscribe()
は、Socket.IO 接続 (例:io.socket.get()
の使用) を介して行われた要求でのみ機能し、HTTP 接続 (例:jQuery.get()
の使用) では機能しません。Sails で WebSockets/Socket.IO メッセージを送信するためのクライアントソケットの使用については、sails.io.js
ソケットクライアントのドキュメント を参照してください。- この関数は実際にデータベースと通信しません! 実際、リソースフルな PubSub メソッドではどれも行いません。むしろ、これらのメソッドはイベント/ルーム/名前空間などの従来の名前を使用してアプリをよりクリーンでデバッグしやすくするために設計された、下位レベルの
sails.sockets
メソッドの上に構築された簡略化された抽象化レイヤーを構成します。