INETを使用してHTTPを閉じることを検出します
質問
私のmochiwebアプリケーションでは、長いHTTPリクエストを使用しています。ユーザーとの接続がいつ死んだかを検出したかったので、それを行う方法を見つけました。
Socket = Req:get(socket),
inet:setopts(Socket, [{active, once}]),
receive
{tcp_closed, Socket} ->
% handle clean up
Data ->
% do something
end.
これは、次の場合に機能します。ユーザーはタブ/ブラウザを閉じるか、ページを再表示します。ただし、インターネット接続が突然死んだとき(WiFi信号が突然失われたとされると)、またはブラウザが異常にクラッシュしたとき、TCPの近くを検出できません。
私は何かが足りないのですか、それともこれを達成する他の方法はありますか?
解決
があります TCP Keepaliveプロトコル そして、それを有効にすることができます inet:setopts/2
オプションの下 {keepalive, Boolean}
.
使用しないことをお勧めします。キープアライブのタイムアウトと最大行為はシステム全体になる傾向があり、結局オプションです。プロトコルレベルでタイムアウトを使用する方が良いです。
HTTPプロトコルには ステータスコード要求タイムアウト それが死んでいるように見える場合、あなたはクライアントに送ることができます。
をチェックしてください after
データを待機するために使用できるブロックを受信したり、タイマーモジュールを使用したり、使用したり、使用できるブロックを受信するか、 erlang:start_timer/3
. 。それらはすべて、異なるパフォーマンス特性とリソースコストを持っています。
他のヒント
デフォルトの「生き続ける」ことはありません(ただし、 サポートされている場合は有効になります)TCPを介したプロトコル:データが交換されないときに接続障害がある場合、これは「サイレント障害」に変換されます。このタイプの障害を自分で説明する必要があります。
これはHTTPにどのように影響しますか? HTTPはステートレスプロトコルです。これは、すべての要求が他のすべてから独立していることを意味します。 HTTPの「維持」機能は、「サイレント障害」がまだ発生する可能性があるため、変更されません。
データが交換された場合のみ この条件を検出できますか(またはTCPが生存している場合)。
HTTP Chunked-Encodingを介して、アプリケーションレベルの維持メッセージを送信することをお勧めします。クライアント/サーバーをスマートにスマートにして、Keep Aliveメッセージを理解し、時間通りに到着したり、接続して接続を再確立したりした場合にそれらを無視してください。