기존에 Java기반에서 APNS 시스템을 구축하여 사용하는 글을 작성한 적이 있습니다. Java에서는 무언가 어렵지 않게 푸시 메시지를 보낼 수 있었습니다만 PHP는 조금 복잡합니다. 핵심적인 내용은 이전 글을 참고하시도록 하시고 이번 글에서는 PHP에서 보내는 방법에 대해 간단히 정리해 보겠습니다.
푸시 전송용 인증서 생성
우선 위와 같이 키체인 접근을 실행하도록 합니다. 그리고 (1)내 인증서를 선택하신후에 자신의 어플의 AppID와 동일한 (2)Apple Development iOS Push Services를 찾도록 합니다. 앞에 있는 화살표를 클릭하여 이것을 확장 할 수 있습니다. 확장하면 위와 같이 (3)개인키가 밑으로 확장됩니다.
(2)Apple Development iOS Push Services를 선택하여 마우스 우클릭 후 보내기를 합니다. 여기서는 apns-dev-cert.p12로 저장을 하겠습니다. 이때에 비밀번호를 생성하게 되는데 적절한 비밀번호를 설정해 주시면 됩니다.
이번엔 (3)개인키를 선택하여 마찬가지로 마우스 우클릭 후 보내기를 합니다. 여기서는 apns-dev-key.p12로 저장하도록 하겠습니다. 지금 하고 있는 작업은 개발용 인증서를 생성하는 과정입니다. 실 서비스용 인증서를 만들때는 마찬가지로 위에서 보이는 Apple Production iOS Push Serivces와 그 밑에 있는 개인키를 이용하시면 됩니다.
위의 과정을 거치게 되면 apns-dev-cert.p12와 apns-dev-key.p12 두개의 파일이 생성되게 됩니다. 적절한 곳에 저장해 두도록 합니다. 저 같은 경우에는 그냥 바탕화면(Desktop)에 저장합니다. 터미널을 실행후에 위의 파일들이 있는 곳으로 이동하여 다음의 명령을 사용하여 PEM파일을 생성합니다.
$ openssl pkcs12 -clcerts -nokeys -out apns-dev-cert.pem -in apns-dev-cert.p12 $ openssl pkcs12 -nocerts -out apns-dev-key.pem -in apns-dev-key.p12
passphrease를 개인키에서 제거하기 위해 다음의 명령을 수행합니다.
$ openssl rsa -in apns-dev-key.pem -out apns-dev-key-noenc.pem
마지막으로 key파일과 cert파일을 통합합니다. 결과적으로 이 파일을 이용하여 APNS에 접근하게 됩니다.
$ cat apns-dev-cert.pem apns-dev-key-noenc.pem > apns-dev.pem
실서비스용 PEM파일도 위와 같은 과정을 거쳐 apns-production.pem 파일로 생성해 주시면 됩니다.
푸시 발송용 PHP 코드 작성하기
다음은 푸시를 발송하기 위한 기본적인 코드입니다. 다음을 참고하셔서 원하시는 형태로 적절히 커스터마이징 하셔서 사용하시면 됩니다.
<?php $deviceToken = '67813b2...af1424b'; // 디바이스토큰ID $message = 'Message received from eye'; // 전송할 메시지 // 개발용 $apnsHost = 'gateway.sandbox.push.apple.com'; $apnsCert = 'apns-dev.pem'; // 실서비스용 //$apnsHost = 'gateway.push.apple.com'; //$apnsCert = 'apns-production.pem'; $apnsPort = 2195; $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, $streamContext); if($apns) { $apnsMessage = chr(0).chr(0).chr(32).pack('H*', str_replace(' ', '', $deviceToken)).chr(0).chr(strlen($payload)).$payload; fwrite($apns, $apnsMessage); fclose($apns); } ?>