2017-12-13 18 views
1

私は自分のウェブサイトで小さなチャットルームサービスを実行していますが、SSEを使用してクライアントに常にチャットの更新を送信していますが、切断や自動再接続、または少なくともそれは何時間もインターネットを傷つけた後に私が見つけたものです。PHP SSEが「切断」しないようにする方法

ここに私のPHP

header("Content-Type: text/event-stream"); 
header('Cache-Control: no-cache'); 

$matchid = $_GET["curMatch"]; 

$root = $_SERVER['DOCUMENT_ROOT']; 
$filename = $root . "/pickup/chat/chatroom.txt"; 
$lastMod = NULL; 

while(true){ 
    if(connection_status() != CONNECTION_NORMAL) { 
     $conn->close(); 
     break; 
    } 

    clearstatcache(); 

    $checker = filemtime($filename); 
    if($checker != $lastMod){  
     $lastMod = $checker; 
     echo "data: 1\n\n"; 
     ob_end_flush(); 
     flush(); 

     usleep(400); 
    } 
} 

はここでjQueryの

matchID = 1; 
if(typeof(EventSource) !== "undefined") {  
    var chatSource = new EventSource("/pickup/php/check-chat-sse.php?curMatch="+matchID); 
    chatSource.onmessage = function(event) { 
     var dt = new Date(); 
     var time = dt.getHours() + ":" + dt.getMinutes() + ":" + dt.getSeconds(); 
     console.log("Chat Server responded: @" +time);   
     console.log(event.data);    

     $.ajax({ 
      type: "POST", 
      url: "/pickup/chat/"+matchID+".txt", 
      datatype: 'text', 
      success: function (response) {  
       $("#chat-content").html(response); 
      } 
     }); 
     if (hidden == true){ 
      $("#chat-toggle").addClass("newMessage"); 
     } 
    } 
} 

そして最後に、コンソールログが

チャットサーバーが応答しますです:チャットサーバーが応答54 :36:20 @ :@ 20:37:24 チャットサーバーが応答しました:@ 20:38:52

これにより、サーバーが再接続するたびに.newMessageクラスが追加され、そうでない場合にユーザーに新しいメッセージがあると思うようになります。 SSEについても同様の問題でより複雑なシステムを実行しているので、解決策を得ることができればすべてが改善されます。

したがって、逆AJAX投票を作成せずに切断して再接続しないようにするにはどうすればよいですか。それはほとんどの人が推薦するものです。どんな提案や助けも大歓迎です。

答えて

0

クライアントブラウザが切断されると、PHPプロセスは自動的にApacheによって閉じられます(Apacheを使用していると仮定していますが、これは指定していないためです)。したがってwhile()ループの最初の4行は必要なく、問題を引き起こしている可能性があります。 (しかし、あなたがそれらを保持していれば、戻り値のログはconnection_status()のログに記録されます。なぜなら、それが接続を閉じる理由を知っているからです。)

30秒ごとに再接続が行われているので、スクリプトは単に時間切れです。以下を追加してください:

set_time_limit(0); 

スクリプトの最上部に追加してください。 (あるいは、whileループの中にset_time_limit(10)のようなものを入れておくのは、より洗練されたアプローチで、真のロックアップコードをキャッチすることです)。

そうでなければ、キープアライブメッセージを送信する必要があります。 (私の本、HTML5 SSEを使用したデータプッシュアプ​​リは、これを実装する方法についていくつかの詳細になります。)


を通りさておき、あなたはSSE本体に実際のチャットメッセージを送信するだけではなく、送信すると考えられてい「新しいデータがあります」というメッセージが表示され、クライアントに追加の要求を行う必要がありますか?全体的にもっと効率的でなければなりません。

+0

これは、テキストファイルのロードブラウザの側を処理していた理由が、サーバーが応答してもテキストファイルが同じであった場合に、他の負荷テストを行うという理由があったようです。サーバーにデータを送信させます。 whileループ内のset_time_limit(10)がより洗練された理由を説明してください。 1週間前まではAJAXのポーリングを使用していたので、SSEには全く新しいものです。私はすぐにその本を買うだろう。 –

+0

@RuanKruger 'set_time_limit'は、無限ループなどのプログラムのバグやリリースされることのないロックを待つように設計されています。ほとんどのPHPスクリプトは1秒間実行すればよいので、デフォルトの30秒は良いバッファ。スクリプトの上部にゼロを設定すると、このセーフティネット機能がオフになります。ループ内に設定することで、そのセーフティネットを元に戻すことができます。詳細はhttp://php.net/set_time_limitを参照してください。 –

関連する問題