개발 Q&A

제목 apns 를 다량 보내는데 속도가 너무 느리네요.
글쓴이 조주상 작성시각 2014/07/21 16:11:24
댓글 : 4 추천 : 0 스크랩 : 0 조회수 : 17042   RSS
몇만개 정도 되는 디바이스 들에게 동시다발적으로 푸쉬를 보내려고 합니다.
 
foreach ($deviceToken as $value) {  
 
			$streamContext = stream_context_create();
			stream_context_set_option($streamContext, 'ssl', 'local_cert', $apnsCert);
	 		$apns = stream_socket_client('ssl://'.$apnsHost.':'.$apnsPort, $error, $errorString, 2, STREAM_CLIENT_CONNECT, $streamContext);

			$payload = array('aps' => array('alert' => $message, 'badge' => 0, 'sound' => 'default'));
			$payload = json_encode($payload); 
  			 

			if($apns)
			{ 
				$apnsMessage = chr(0).chr(0).chr(32).pack('H*', str_replace(' ', '', $value)).chr(0).chr(strlen($payload)).$payload;
				fwrite($apns, $apnsMessage); 
				$success_count++; 
				echo "$value 
";
		    } else {  
				$fail_count++;
			}  
		 	$cnt++;
		}


위와 같이 1개의 메세지를 보내고  fclose를 하고 
새로 연결을 하고 하는걸 반복하면 제가 원하는 다량의 푸쉬메세지가 느리게 나마 전달은되는데

아래와 같이 100 번째 단위로 apns 를 재 연결 시도해서 전송을 하면
절반 이상의 푸쉬가 전송되지 않습니다.
result 값은 전송에 성공했다고 뜹니다.
		foreach ($deviceToken as $value) {  

  	  		if ($cnt0 == 0) {
  	  			if ($apns != null) {
					fclose($apns);
					$apns = null;   
			  	} 

				$payload = array('aps' => array('alert' => $message, 'badge' => 0, 'sound' => 'default'));
				$payload = json_encode($payload); 
				$streamContext = stream_context_create();
				stream_context_set_option($streamContext, 'ssl', 'local_cert', $apnsCert);
		 		$apns = stream_socket_client('ssl://'.$apnsHost.':'.$apnsPort, $error, $errorString, 2, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $streamContext);
 
  			}

			if($apns)
			{ 
				$apnsMessage = chr(0).chr(0).chr(32).pack('H*', str_replace(' ', '', $value)).chr(0).chr(strlen($payload)).$payload;
				fwrite($apns, $apnsMessage); 
				$success_count++;  
		    } else {  
				$fail_count++;
			}  
		 	$cnt++;
		}

 다음글 rewrite 관련 질문입니다. (2)
 이전글 안녕하세요 서버컴을 받았는데 idc 저렴한곳 추천바랍니... (5)

댓글

Artz / 2014/07/22 20:24:26 / 추천 0
apns의 경우, 전송 도중 에러가 발생하면 apns 서버는 6 바이트 패킷을 리턴하고 접속을 끊습니다.
fwrite가 실패했을때, fread로 리턴된 패킷을 읽어와서 원인을 파악해봐야 할 것 같으며,
접속이 끊기기 때문에 fwrite 실패시엔 socket connection을 다시 생성하는 루틴을 추가해야 할 것 같습니다.
조주상 / 2014/07/23 13:05:32 / 추천 0
Artz 님 답변감사합니다.

답변주신대로 fwrite된 값을 fread 로 읽어왔는데

모두 false로 떨어지게 되는데 제가 한 방법과 다른 방법이 있나요?

fread($apns,6) 로 확인 했습니다.
 
Artz / 2014/07/24 10:46:22 / 추천 0
APNS 서버에 정상적으로 푸시데이터가 전송된 경우에는 아무것도 리턴하지 않습니다.
그렇기 때문에 fwrite가 실패했을 경우에만 fread하여 어떤 원인으로 실패했는지 확인해야 합니다.
이 일련의 과정들이 모두 정상인데도 푸시 수신이 안된 경우에는,
여러가지 테스트를 진행하면서 원인을 확인할 수 밖에 없을 것 같네요.
조주상 / 2014/07/24 10:51:48 / 추천 0
답변감사합니다.

fwrite 를 하고 나면 한번도 false를 반환하지 않고 진행이 됩니다.

혹시 제가 참고할만한 소스를 올려주실수 있으시면 부탁드리겠습니다.