私は、自分のプロジェクトで使用する単純なロング ポーリング サービスを実装しようとしてきました。成功すれば、SAAS としてリリースするかもしれません。これらは私がこれまでに試した 2 つのアプローチで、どちらも Node.js を使用しています (バックグラウンドで PostgreSQL をポーリングしています)。
1. すべてのクライアントを同じ間隔で定期的にチェックする
すべての新しい接続は、接続のキューにプッシュされます。これは、一定の間隔でウォークスルーされます。
var queue = [];
function acceptConnection(req, res) {
res.setTimeout(5000);
queue.push({ req: req, res: res });
}
function checkAll() {
queue.forEach(function(client) {
// respond if there is something new for the client
});
}
// this could be replaced with a timeout after all the clients are served
setInterval(checkAll, 500);
2. 各クライアントを別々の間隔でチェックする
すべてのクライアントは、ticker
新しいデータをチェックする独自のものを取得します
function acceptConnection(req, res) {
// something which periodically checks data for the client
// and responds if there is anything new
new Ticker(req, res);
}
これにより、各クライアントの最小レイテンシが低く保たれますが、多くのタイムアウトを設定することでオーバーヘッドも発生します。
結論
これらのアプローチは両方とも問題を非常に簡単に解決しますが、特にすべてのクライアントのすべてのチェックでデータベースをポーリングしているため、1,000 万のオープン接続などに簡単にスケールアップできるとは思いません。
データベースなしでこれを行うことを考え、開いているすべての接続に新しいメッセージをすぐにブロードキャストしましたが、ブロードキャストが発生している間にクライアントの接続が数秒間切断された場合、それは永続的ではないため失敗します。つまり、基本的に、クライアントが初めてポーリングするときに、履歴でメッセージを検索できる必要があります。
ここでの 1 つのステップは、入ってくる新しいデータ (CouchDB の変更通知?) をサブスクライブできるデータ ソースを用意することだと思いますが、全体像で何かが欠けているのではないでしょうか?
スケーラビリティの高いロングポーリングを行うための通常のアプローチは何ですか? 私は特に Node.js に縛られているわけではありません。実際には、理由のある他の提案を好むでしょう。