早速、今日の話題を始めましょう。このプログラムを見て、最も価値があるのは、nodejs を使用してロングリンク モードのリフレッシュ技術を実装する方法を示していることだと感じます。
(このプログラムは詳しく紹介しませんが、この関数に焦点を当てます)
Client.js
コードは次のとおりです。
、dataType: "json"
、データ: {since: CONFIG.last_message_time、id: CONFIG.id }
、エラー: function () {
addMessage("", "ロングポーリングエラー。再試行しています...", new Date(), "error");
transmission_errors = 1;
//エラー時にサーバーをフラッディングしないでください。再試行する前に 10 秒待ってください。
setTimeout( longPoll, 10*1000);
}
, success: function (data) {
transmission_errors = 0;
//すべてがうまくいった場合は、すぐに別のリクエストを開始します
//応答には長い時間がかかります
//どのくらいかかりますか?別のメッセージがあるまで待機します
//その後、メッセージを返して接続を閉じます
//データを取得すると接続が閉じられ、再度longPollします。
longPoll(data);
}
})
これはクライアントのコードです。 .js このコードを見ると、すぐに「再帰」という 2 つの単語が思い浮かぶはずです。 longPoll メソッドで、longPoll メソッドを再度呼び出します。これは一般的な再帰呼び出しです。
このコードのセマンティクスに基づくと、初めてロードするときに、longPoll メソッドが呼び出されて、「/resv」から値を非同期的に取得し、成功すると、success メソッドが実行されます。 longPoll メソッドはすぐに再度呼び出されます。失敗した場合は、エラー関数を実行し、10 秒ごとに longPoll メソッドを再度呼び出します。もちろん、error メソッドを実行できる回数には一定の制限があり、これは変数transmission_errorsxによって制御されます。
質問があるかもしれませんが、データを取得するために再帰的にループすることでサーバーに負担がかかりますか?取得するデータがない場合でも、このサイクルは続くのでしょうか?もちろん、答えはノーです!さらに、nodejs は独自の特性を使用して、この問題をうまく解決します。次に、
Server.js
サーバーが上記のクライアント呼び出しにどのように応答するか、コア コードを見てみましょう:
コードをコピー
コードは次のとおりです:
});
fu.get() が何を意味するかについては、このチュートリアルとは関係ありません。つまり、クライアントの呼び出しに応答できるということだけを知っておいてください。上記のコードは、セッションに対するいくつかの操作に加えて、チャネルのクエリ メソッドを呼び出すだけです。渡されるパラメータに注意してください:
since は時間を記録します。
匿名メソッドはメッセージ パラメータと 2 つのアクションを受け取ります: 1. セッション時間を更新します。 2. json を返します。つまり、メッセージを返します。クライアントに。
ここでメッセージを直接返すことはできないのですか? 操作するためにチャネル内でメソッドを定義する必要があるのはなぜですか?回答: その場合、返す情報がない場合でも、サーバーとクライアントは常にデータと対話します。
読んでみましょう!
チャネルの定義方法を確認します:
コードをコピーします
コードは次のとおりです:
var MESSAGE_BACKLOG = 200,
SESSION_TIMEOUT = 60 * 1000;
var チャネル = 新しい関数 () {
var メッセージ = [],
コールバック = this.appendMessage = function (nick, type, text) {
var m = { nick: ニック
, type: type // "msg", "join", "part"
, text: text
、タイムスタンプ: (new Date()).getTime()
};
switch (type) {
case "msg":
sys.puts("<" nick) "> " text);
break;
case "join":
sys.puts(nick " join");
case "part":
sys .puts(ニック " 部分");
break;
}
messages.push( m );
//shift() メソッド配列の最初の要素を削除し、最初の要素の値を返すために使用されます
callbacks.shift().callback([m]);
}
while (messages.length > ; MESSAGE_BACKLOG )
messages.shift();
};
this.query = function (since, callback) {
varmatching = []
for (var i = 0; i var message =messages[i]
if (message.timestamp > because)
matching.push(message)
; .length != 0) {
callback(matching);
} else {
callbacks.push({ timestamp: new Date(), callback: callback }); ;
// 古いコールバックをクリアします
// 最大 30 秒間待機できます。
var now = new Date();
while (コールバック) .length > 0 && now - callbacks[0].timestamp > 30*1000) {
}
}; >};
チャネルには、3 秒ごとに実行される 2 つの変数、2 つのメソッド、および setInterval 関数が定義されています。
まずクエリ メソッドを見てみましょう。
クエリ メソッドは 2 つのパラメータを受け取ります:
since: 時間を記録します
callback: 上記の channel.query メソッドを呼び出すときに渡される匿名関数 (JS の場合) , 関数はパラメータとして渡すことができ、受信後に直接呼び出すことができます。)
現在のチャット レコード キューはメッセージに保存されており、クエリ メソッドは条件を満たすチャット レコードを見つけて配置します。キューにあります。 matching.length>0 の場合、コールバックで受け取った関数が呼び出されます。つまり、マッチングが JSON 形式でクライアントに返されます。しかし。 。 。次に重要なポイントです! ! !
コードをコピーします
コードは次のとおりです:
if (matching.length != 0) {
callback(matching); } else { callbacks.push({ timestamp: new Date(), callback: callback }); if matching.length では、この状態を永遠に続けることはできません。誰かが毎秒チャット メッセージを送信してきたらどうしますか?
次に、appendMessage (チャット メッセージの追加) メソッドを見てください。
このメソッドの最初の部分は、受信パラメーターを受け取り、それらを組み合わせて m セットを作成し、それを使用するだけです。 sys.puts を実行して、メッセージ チャット メッセージ キューに m を挿入します。次が重要なポイントです:
コードをコピーします
コードは次のとおりです:
while (callbacks) .length > ; 0) {
//shift() メソッドは、配列の最初の要素を削除し、最初の要素の値を返すために使用されます
callbacks.shift().callback([m]); } 次に、コールバックが保存されているかどうかを判断する必要があります。保存されている場合は、1 つを実行し、実行が完了するまで 1 つを削除します。返されるチャット メッセージがなくなる前に、誰かがリクエストを行っても、システムはこれらのリクエストを実行せず、コールバック リストに追加しなかったためです。 誰かがチャット メッセージを送信したので、add メソッドを実行するときに、未実行のリクエストをすべて再度実行する必要があります。
一般的な理解は次のとおりです。「あなたは私にリクエストを送信しましたが、返信する新しいメッセージはまだありません。誰かが新しいメッセージを送信したら、すぐに返信します。」
理解できるかわかりませんが。 。 。
このステップは完了です。最後のステップは、期限切れのコールバックを 3 秒ごとにクリアすることです。これは理解するのが難しくありません。
概要
Nodejs は、独自のイベント駆動型言語機能を使用して、長いリンクの更新機能を実装しています。これにより、目を覚ますことができます。とても恩恵を受けたと感じています。時間をかけてチュートリアルを書いて皆さんと共有し、私自身の理解を深めたいと思います。