회사일중에 소켓을 이용해서 다른 웹서비스의 xml데이터를 받아서 처리하는 작업이 있었다.
별 문제 없이 처리했으나 서비스를 하던중 문제가 발생했다.
xml을 제공하는 웹서비스의 서버 상태가 불안해서 처리 작업이 진행이 안되고 멈춰있는 경우가 종종 발생한 것이다.
소켓 연결 실패 라던가 무한 루프 등의 예외 처리는 해 놓은 상태였지만
소켓 연결이 성공한 상황에서 데이터를 받지 못해서 처리작업이 신호대기 상태로 멈춰있는 경우였다.
방법이 없을까 고민하던중 php.net에서 다음과 같은 함수를 찾았다.
stream_set_timeout와 socket_set_timeout이다.
다른 함수처럼 보이지만 결과는 같다.
stream_set_timeout은 데이터 스트림 수신 대기시간의 타임 아웃을 설정하는것이고
socket_set_timeout은 소켓 연결중 데이터 송수신 없이 대기하는 타임아웃을 설정하는 것이다.
실제 테스트에서도 같은 결과를 보여주었다.
php.net의 예제 소스들을 보면 stream_set_blocking또는 socket_set_blocking를 필히 false로 설정하라고 나와 있었지만,
이번의 경우에는 설정을 했을경우에 오히려 제대로 동작하지 않았다.
그 이유는 blocking모드를 false로 설정하게 되면 송수신이 완료하게 되었을 경우에만
데이터를 출력이나 socket의 상태값을 반환하기 때문이다.
timeout값을 설정한다고 해서 연결이 자동적으로 끊어지는것이 아니기 때문에
fget이나 feof등 의 데이터 수신 구문이 있는곳에는 필히
socket_get_status를 이용해서 수시로 연결 상태를 확인한후
timeout상태가 발생하면 예외 처리를 해주어야 한다.
다음은 샘플 소스이다.
별 문제 없이 처리했으나 서비스를 하던중 문제가 발생했다.
xml을 제공하는 웹서비스의 서버 상태가 불안해서 처리 작업이 진행이 안되고 멈춰있는 경우가 종종 발생한 것이다.
소켓 연결 실패 라던가 무한 루프 등의 예외 처리는 해 놓은 상태였지만
소켓 연결이 성공한 상황에서 데이터를 받지 못해서 처리작업이 신호대기 상태로 멈춰있는 경우였다.
방법이 없을까 고민하던중 php.net에서 다음과 같은 함수를 찾았다.
stream_set_timeout와 socket_set_timeout이다.
다른 함수처럼 보이지만 결과는 같다.
stream_set_timeout은 데이터 스트림 수신 대기시간의 타임 아웃을 설정하는것이고
socket_set_timeout은 소켓 연결중 데이터 송수신 없이 대기하는 타임아웃을 설정하는 것이다.
실제 테스트에서도 같은 결과를 보여주었다.
php.net의 예제 소스들을 보면 stream_set_blocking또는 socket_set_blocking를 필히 false로 설정하라고 나와 있었지만,
이번의 경우에는 설정을 했을경우에 오히려 제대로 동작하지 않았다.
그 이유는 blocking모드를 false로 설정하게 되면 송수신이 완료하게 되었을 경우에만
데이터를 출력이나 socket의 상태값을 반환하기 때문이다.
timeout값을 설정한다고 해서 연결이 자동적으로 끊어지는것이 아니기 때문에
fget이나 feof등 의 데이터 수신 구문이 있는곳에는 필히
socket_get_status를 이용해서 수시로 연결 상태를 확인한후
timeout상태가 발생하면 예외 처리를 해주어야 한다.
다음은 샘플 소스이다.
$sock = fsockopen($host, 80, $errno, $errstr, 30); if(!$sock){ echo "Unable to get server status"; }else{ $out = "GET /server.php HTTP/1.1\r\n"; $out .= "Host: $host\r\n"; $out .= "Connection: Close\r\n\r\n"; fwrite($sock, $out); stream_set_blocking($sock, FALSE ); stream_set_timeout($sock, $timeout); $info = stream_get_meta_data($sock); while (!feof($sock) && !$info['timed_out']) { $file .= fgets($sock, 4096); $info = stream_get_meta_data($sock); } fclose($sock);
'프로그래밍 > PHP' 카테고리의 다른 글
아이폰 유저에이전트 (USER_AGENT) (0) | 2010.04.16 |
---|---|
PHP 컨스트럭터와 디스트럭터 (0) | 2010.03.17 |
PHP 작업시 도움이 되는 함수 (0) | 2010.01.20 |
PHP 이미지 변환 BMP to JPG (0) | 2009.12.09 |
php 정규식 문자열 체크 (0) | 2009.10.23 |