2011-09-08 24 views
17

node.jsで長いポーリングを行っています
基本的に、node.jsサーバーはユーザーからの要求を受け入れ、いくつかの更新を確認します。更新がない場合は、タイムアウト後に更新をチェックします。
しかし、ユーザーがタブを閉じたか、別のページに行った場合はどうなりますか?私の場合、スクリプトは動作し続けます。
ユーザがリクエストを中止したとき(接続を閉じたとき)に、node.jsがチェックまたは検出したり、イベントをキャッチする方法はありますか?node.jsサーバーで接続が切断されたかどうかを確認する方法

答えて

17

おかげで私は、「閉じる」イベントをキャッチすることができましたが、私はいくつかの追加の調整をしなければなりませんでした。

「閉鎖」イベントを捕捉するだけで問題が解決されなかった理由は、クライアントがnode.jsサーバーに要求を送信すると、サーバーが接続がまだ開いていればサーバー自体が情報を取得できないことですクライアントに何かを送り返します(私が理解する限り - これはHTTPプロトコルのためです)。
追加の調整は、応答に何かを書き込むことでした。
これを防止するもう一つのことは、 'application/json'として 'Content-type'があることです。これを 'text/javascript'に変更することで、接続を閉じることなく「ホワイトスペース」を時折ストリームすることができました。最後に
は、私はこのようなものだった:

var server = http.createServer(function(req,res){  
    res.writeHead(200, {'Content-type': 'text/javascript'}); 

    req.connection.on('close',function(){  
     // code to handle connection abort 
    }); 

    /** 
    * Here goes some long polling handler 
    * that performs res.write(' '); from time to time 
    */ 

    // some another code... 
}); 
server.listen(NODE_PORT, NODE_LISTEN_HOST); 

を私の元のコードははるかに大きいので、私はちょうど敏感な部分を表示するためにそれをたくさんカットしなければなりませんでした。

もっと良い解決策があるかどうかを知りたいが、これは現時点で私のために働いている。

4

を試す確認するか、検出またはキャッチするためのNode.jsの中に方法はあります ユーザーがリクエストを中断した場合(接続を終了しましたか?)

http.ServerRequest close eventを試すことができます。簡単な例:Miroshkoのyojimbo87の答えに

var http = require("http"), 
    util = require("util"); 

var httpServer = http.createServer(function(req, res) { 
    util.log("new request..."); 

    // notify me when client connection is lost 
    req.on("close", function(err) { 
     util.log("request closed..."); 
    }); 

    // wait with response for 15 seconds 
    setTimeout(function() { 
     res.writeHead(200, {'Content-Type': 'text/plain'}); 
     res.write("response"); 
     res.end(); 

     util.log("response sent..."); 
    }, 15000); 
}); 
httpServer.listen(8080); 
util.log("Running on 8080"); 
16

あなたはreq.on('close', function(err) { ... });代わりのreq.connection.on('close', function(err) { ... });

非常に重要な違いがありますを使用する必要があります。 req.connection()がreq.connection.on()の間にreq.on()がこの要求にリスナーを追加すると、クライアントとサーバー間の(キープアライブ)接続にリスナーが追加されます。 req.connection.on()を使用する場合、クライアントが接続を再利用するたびに、同じ接続にもう1つのリスナーを追加します。最後に接続が切断されると、すべてのリスナーが起動されます。

機能スコープは、通常、サーバロジックを壊すことから安全ですが、それでも危険です。幸いにも少なくともNodeJS 0.10。図26は、このユーザーに警告するのに十分なスマートです:

(node) warning: possible EventEmitter memory leak detected. 11 listeners added. Use emitter.setMaxListeners() to increase limit. 
Trace: 
    at Socket.EventEmitter.addListener (events.js:160:15) 
    at Socket.Readable.on (_stream_readable.js:689:33) 
    ... 
2

私はExpress.js(〜4.10.6)を使用していて、次のコードは、私のために正常に動作している:

//GET Request: 
app.get('/', function(req, res){ 
    req.on('close', function(){ 
     console.log('Client closed the connection'); 
    }); 
}); 

次第ブラウザのタブを閉じると、ブラウザは接続を閉じ、コールバック関数は期待通りに実行されます。

+0

このページには、一般的にクローズドTCP接続の検出に関する詳細情報があります。http://blog.stephencleary.com/2009/05/detection-of-half-open-dropped.html –

関連する問題