2016-08-30 18 views
3

CURLリクエストを機器に送信する自動同期機能があり、私が持っているすべての機器(60など)に対してこのリクエストを行います。問題は次のとおりです。
- 通信が成功した場合、正常に動作します。
- しかし、通信が失敗した場合、Webページはタイムアウトがなくなるまで待機します。だから、クライアント側は3〜4分間クラッシュします...私はその3-4分でデータのロードを停止する重要なグリッドを持っています。PHP CurlタイムアウトがクラッシュするJavascriptクライアント側

自動同期は、javascriptの関数で、以下のPHPコントローラを呼び出すAJAXリクエストを行います。どうすればこれを防ぐことができますか?他に何を試していいのかわかりません... AJAXは非同期なので、なぜWebページが停止するのか分かりません。

コントローラー:

$list = $panels_repository->getNetwork(); 

      $thread = new PollingThread($list); 
      $thread->start(); 
      $thread->join(); 

      $result = $thread->result; 
      $resultLength = sizeof($result); 

      //... 

スレッド:

class PollingThread extends Thread { 
private $panels_list; 
private $alarm_status; 
public $result; 

public function __construct($list) { 
    $this->panels_list = $list; 
} 

public function run() { 
    $panels_list = $this->panels_list; 

    $alarmsUpdated = array(); 
    $panels = array(); 

    foreach($panels_list as $panel) { 
     $alarms_list = $panel->getAlarmsList(); 

     //Get updated alarms status 
     $panel->getDiagnosticStatus($alarms_list); 

     //Save the results 
     array_push($alarmsUpdated, $alarms_list); 
    } 

    $this->result = $alarmsUpdated; 

} 

getDiagnosticStatus

$input = "<?xml version='1.0' encoding='ISO-8859-1'?> 
       <?getParameters message?> 
       <displayMLRequest xmlns='http://www.peek.se/DisplayML/' version='1.12' 
            dateTime='2008-01-10T15:09:51+02:00'> 
        <getParameters/> 
       </displayMLRequest>"; 

    $ch = curl_init(); 
    curl_setopt($ch, CURLOPT_URL, $url); //Set IP to communicate 

    //Set POST XML Input 
    curl_setopt($ch, CURLOPT_POST, 1); 
    curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: text/xml')); 
    curl_setopt($ch, CURLOPT_POSTFIELDS, $input); 

    //Return response as string & TimeOuts 
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); 
    curl_setopt($ch, CURLOPT_TIMEOUT, 10); 

    //Execute 
    $output = curl_exec($ch); 

    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); 

    curl_close($ch); 

Javascriptを:

$('#stations_tree').on('changed.jstree', function (e, data) { 
    //.... 

    var dataObject = { 
     type: "Selected", 
     childrenID: childrenID_array, 
     parentsID: parentsID_array 
    }; 

    $.ajax({ 
     type: "POST", 
     url: "controllers/PanelsController/", 
     data: dataObject, 
     cache: false, 
     success: function() 
     { 
      $("#dg_selected_stops").jsGrid("loadData"); 
      $("#dg_selected_pids").jsGrid("loadData"); 
     } 
    }); 

}).jstree({ 
    plugins: ["checkbox", "state", "types"], 
    "types": { 
     "default": { 
      "icon" : false 
     } 
    }, 
    core: { 
     data: { 
      url: "json/stations.json", 
      dataType: "json", 
      success: function() { 
       //Save Panels Network as session variable 
       var dataObject = { 
        type: "Network" 
       }; 

       $.ajax({ 
        type: "POST", 
        url: "controllers/PanelsController/", 
        data: dataObject, 
        cache: false, 
        success: function() { 
         //Get EquipmentStatus for each panel 
         var dataType = { 
          type: "Save" 
         }; 

         $.ajax({ 
          type: "POST", 
          url: "controllers/EquipmentStatusController/", 
          data: dataType, 
          cache: false, 
          success: function() { 
           //Status Unknown 
           changeTreeIcons(); 
           loadAlarmsData(); 

           polling(); 
          } 
         }); 
        } 
       }); 
      } 
     } 
    } 
}); 
-

機能ポーリング()JSがタイムアウトするまで停止し

function polling() { 
var dataObject = { 
    type: "Polling", 
}; 

$.ajax({ 
    type: 'POST', 
    url: "controllers/DatabaseController/", 
    data: dataObject, 
    success: function(response) { 
     //loadAlarmsData(); 
     //changeTreeIcons(); 
    } 
}); 

}

EDITなくなって:を私は、私が始めたポーリング後にAJAX要求を行うことをしようとすることを確認していますウェブページは、PHPスクリプトが完了した後にそのリクエストを行います。そのため、ブロックするJSは、ajaxリクエストでloadDataのテーブルです。どうすれば解決できますか?

+0

は、これらの悪いCURLの要求にスローされるすべてのエラーはありますか? –

+0

@TheOneandOnlyChemistryBlobいいえ、getDiagnosticStatusで "test"をエコーし​​た場合、ウェブは6-7回印刷されます。*ホスト名172.18.56.132がDNSキャッシュに見つかりました *試行172.18.56.132 ... *接続が10000ミリ秒後にタイムアウトしました *接続を閉じる0 – BackSpace

+2

ifファイルのテストで1つのカールリクエストのみを実行すると、問題は、Webページを停止し、その後、PHPではなくJavaScriptを投稿することです –

答えて

2

コピー/ペーストのための完全な解決策ではありませんが、問題の解決方法を知ることができます。あなたは次に試すことができます(php-fpmのみ)。

フロントエンド側で、jsを使用して同期を実行し、コントローラを呼び出すと、コントローラのクライアント側の がブラウザに応答を送信し、fastcgi_finish_request()にコールしてから、CURL操作が開始されます。この関数はすべての応答データをクライアントにフラッシュし、要求を終了しますが、PHPスクリプトはジョブを続行します。 PollingThreadで

... 

$list = $panels_repository->getNetwork(); 

$key = 'my_unique_operation_key'; // it key need you for get data on client side 
$resp = [ 
    'status'=>'start', 
    'operation_key' => $key 
]; 
echo json_encode($resp); 
fastcgi_finish_request(); // close connection and continue ... 

$thread = new PollingThread($list, $key); // send $key also 
... 

// call controller and start operation 
$.ajax({ 
    url: '/controller/uri/here', 
    beforeSend: function() { 
    // here you can place spinner or progress bar ... 
    }, 
    success: function(json) { 
    // in json you get progress key after fastcgi_finish_request() 
    // and run visual progress 
    getDataPartially(key); 
    } 
}); 

// load data partially 
function getDataPartially(key){ 
    var timerId = setInterval(function() { 
    $.ajax({ 
     url: '/controller/uri/here/getDataPartially_action?key=' + key,  
     success: function(json) { 
     // in json you have data for grids and progress info 
     // if json contains finish info stop progress 
     clearInterval(timerId); 
     // hide progress bar and etc ... 
    } 
});}, 2000); 
} 

P.S.:フロントエンド側で

function getDataPartially_action(){ 
    $key = $_GET['key']; // not forget validate 
    ... 
    $jsonData = $memcache_obj->get('operation_'.$key); // get current state from memcache by key 
    echo $jsonData; 
    exit(); 
} 

... 
foreach($panels_list as $panel) { 
    $alarms_list = $panel->getAlarmsList(); 

    //Get updated alarms status 
    $panel->getDiagnosticStatus($alarms_list); 

    //Save the results 
    array_push($alarmsUpdated, $alarms_list); 

    ... 
    // save operation progress for example in memcache 
    $progressData = some data about progress and $alarmsUpdated, etc... 
    $memcache_obj->set('operation_'.$key, json_encode($progressData)); 
} 

どこかのコントローラは、データ部分を返すアクションを追加 CURL機能では、CURLOPT_PROGRESSFUNCTIONを使用して、進行状況に関する詳細情報を取得することができます

$ch = curl_init(); 
    curl_setopt ... 
    curl_setopt($curl, CURLOPT_PROGRESSFUNCTION, 'curl_progress_callback'); 
    ... 
// where curl_progress_callback is: 

    function curl_progress_callback($dltotal, $dlnow, $ultotal, $ulnow){ 
     $curlInfo = curl_getinfo($ch); // a lot info about connection 
     echo $curlInfo['connect_time']; 
     echo $curlInfo['http_code'] ...  
    } 
+0

助けてくれてありがとう!あなたの答えを分析しています。あなたの要点は、fastcgi_finish_request()を使用することです。クライアント側は停止しません。その後、getDataPartiallyで情報を読み込みますか?私の疑いはURLにあります。どこにgetDataPartiallyを置くのですか?申し訳ありませんが、ちょっと初心者です:/ – BackSpace

+0

@BackSpace、右、getDataPartiallyで情報を読む必要があります。実装には、Controllerにアクションを追加し、getDataPartially()関数でこのアクションurlを呼び出す必要があります。私は自分の答えを更新しました。 –

+0

現時点で私はあなたの答えを実装しようとしています。私はJavaScriptコードで私の質問を更新しました、あなたはそれを見ることができますpls?私は問題がPHPであると思うが、私は知らない。 – BackSpace

関連する問題