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连接超时后的异常将无法捕获。

这个一个相对简单而完善的连接处理就建立好了。

 

 

 

 

posted @ 2013-06-27 10:58  albafica  阅读(7839)  评论(0编辑  收藏  举报