webservice連接超時處理


之前和客戶方一套系統連接webservice經常出現連接超時的問題,至於連接為何超時,雙方各執一詞,誰吃飽撐得往自己身上攬臟水啊。

由於之前沒有對腳本的執行時間進行超時處理,導致系統操作人員陷入無限等待中,所以在連接webservice時添加了終端操作,當連接超過限定時間時,認為連接失敗阻塞了,就放棄連接。

 1 ini_set('default_socket_timeout', 13);
 2 set_time_limit(15);
 3 $errno = ini_get('error_reporting');
 4 error_reporting(0);
 5 register_shutdown_function('runError');//和諧輸出頁面執行超時錯誤
 6 $time_start = microtime(true);
 7 try{            
 8     $client = new soapclient(C('webservice_url'));
 9     $client->soap_defencoding = C('webservice_encoding');
10     $client->xml_encoding = C('webservice_xml_encoding');
11     $username = C('webservice_u');
12     $password = C('webservice_p');
13     $aryResult = $client->__soapCall("ImportOrder", array(array('username' => $username, 'password' => $password, 'ordermesg' => $list, 'datatype' => 'json')));
14     error_reporting($errno);
15     $time_request = (microtime(true)-$time_start);
16 }catch(Exception $e){
17     $time_request = (microtime(true)-$time_start);
18     if($e->getMessage() == 'Error Fetching http headers' && ini_get('default_socket_timeout') < $time_request) {
19         throw new SoapTimeoutException('webservice連接可能超時'.' It took '.$time_request.' and the limit is '.ini_get('default_socket_timeout')    );
20     }
21     // E: Not a timeout, let's rethrow the original exception
22     throw $e;
23 }
1 function runError () {
2     echo '程序執行超時,請重新打開';
3 }

程序的超時有兩種,首先是webservice連接本身建立通訊了,但是一直沒有返回數據,所以上面的代碼中定義了webservice的連接超時時間為13s,這是定義在php.ini中的,如果webservice連接超過13s,程序就拋出連接超時的異常。

另外一種是腳本執行超時,有時候可能是瀏覽器,網絡等各種原因,webservice還沒有連接,腳本就陷入了假死狀態,所以定義腳本超時時間,系統默認腳本執行時間為30s,這邊定義為15s,手冊上有提到,當調用set_time_limit時,計時器會從0開始計時,前面各種元素加載的時間並不計算在內。此處結合上面的webservice連接超時時間,如果webservice連接上了后產生阻塞,13s內便會拋出異常,所以不會引起15s才觸發的腳本中斷。所以,如果腳本中斷基本可以認定webservice沒有連接成功。當然,我們查看過webservice連接情況,正常情況下,2s內連接的建立,數據的返回都完成了,所以現有的設計基本不會引起太大的問題。不過,這也只是猜測,前段時間由於數據量較多,網絡又延遲,webservice連接成功后沒有及時返回數據,也沒有達到13s的連接超時,但是由於前面建立連接時花了不止2s,腳本執行到15s時,中斷了腳本,再重建連接返回了非預期的數據。所以,如果願意等待的話,這兩者之間的時間最好可以相差大點。

腳本中斷后系統會報錯,所以,這邊還有個處理技巧,先記下當前的報錯級別,然后重置為0,即不報任何錯誤,不自動拋出異常,然后腳本超時后,調用register_shutdown_function注冊一個自定義函數,超時后會自動調用這個函數,顯示自定義的信息。當然,如果webservice連接成功的話,還是需要回復先前的錯誤級別,不然,webservice連接超時后的異常將無法捕獲。

這個一個相對簡單而完善的連接處理就建立好了。

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM