質問: 状態JS+PHPでリアルタイムのチャットをロングポーリングで実装しています。 JS側でリクエストを投げ、PHP側で1秒間隔でチェックを行い、タイムアウトを考慮して20秒程度で一旦返す形で実装しております。 サーバにajaxでリクエストを投げてからサーバ側で処理している時に、ページ遷移(更新)を行うと 前述のリクエストが返ってくるまでページ読み込みがされない状態となり、最大20秒前後待つ形になってしまいました。 相談内容 ----- 次項の環境は変えずに、同一セッションからの複数リクエストが直列化されない様にすることは可能でしょうか。 ex)Apacheの設定変更や、jsでの設定項目など 難しい場合、素直にjs側でPromiseなりsetIntervalなどでポーリング処理を行いたいと思います。 環境 --- Apache2.4 PHP5.6 MySQL5.6 全て1台にまとまっております。 簡易ソース及び実行結果 ------------ ``` for(var i=0;i<5;i++){ (function(i){ console.log("sent"); $.ajax({ url:url, type:"POST" }).done(function (response) { console.log("ok"); }); })(); } ``` ``` function xxxx(){ for($i=0;$i<20;$i++){ //更新チェック処理及び離脱処理 sleep(1); } echo (json_encode($result)); exit(); } ``` ``` (リクエストを投げる時はほぼ同時) sent sent sent sent sent (20秒間隔で結果が返ってくる) ok ok ok ok ok ``` 試したこと ------ xhr.abort()でのリクエストキャンセル要求 →サーバ側の処理まで中断されないため、ロングポーリングが動ききってからページリロードなどのリクエストが処理されました。 試してみたいが試せてないこと --------------- HTTP/2でのリクエストの場合どうなるのか? APIサーバを独立させ冗長化した後にリクエストを分けた場合には解決するのか? nginxなどのApache以外のWebサーバを選択した場合には解決するのか?
回答: > > 次項の環境は変えずに、同一セッションからの複数リクエストが直列化されない様にすることは可能でしょうか。 > > > むしろ、普通に組めばApache+PHPの処理は**並列にさばけます**し、PHP(フレームワークなども含む)で並列リクエストをロックしているような状況でなければ、1回に1つしかリクエストを処理できないのは**設定ミス**に近いと考えます(実運用には、到底耐えられないことでしょう)。 実際の詳細な設定は、ApacheでどのMPMを選んでいるか、そしてPHPをどう動かしているかによります。