APNS ~Proxyの向こう側~ | 仕事たのしいなーもー

仕事たのしいなーもー

SEブログです。日々の発見や関心を掲載しています。

ある程度おっきい基盤上でAPNS通知をやるとしたら
Proxyをくぐって流す必要も出てくると思う。
そんな時に以下を参考にしていただければと。


define('APNS_SERVICE_URL', 'gateway.push.apple.com:2195');
define('PROXY_HOST', '環境にアワセテ');
define('PROXY_PORT', '環境にアワセテ');

$sslContext = stream_context_create(array(
'ssl' => array('local_cert' => '環境にアワセテ.pem')
));

//PROXYへ socketを開く
$socket = stream_socket_client('tcp://'.PROXY_HOST.':'.PROXY_PORT, $errno, $errstr, 10, STREAM_CLIENT_CONNECT, $sslContext);

if (!$socket){
throw new Exception('connection failed;');

}

// PROXY-AppleへのCONNECTリクエスト
$request = array();
$request[] = 'CONNECT '.APNS_SERVICE_URL.' HTTP/1.1';
$request[] = 'Host: '.PROXY_HOST;

if(!fwrite($socket, implode("\r\n", $request)."\r\n\r\n")){
throw new Exception('connection failed;');
}

// PROXY-Appleからのレスポンス受領
$response01 = '';
while(!feof($socket)){
$response01 .= fgets($socket, 4096);
if(preg_match('/^http/i', $response01)) break;
}

// socketへSSL通信の設定を適用
stream_socket_enable_crypto($socket, true, STREAM_CRYPTO_METHOD_SSLv3_CLIENT);
stream_set_blocking($socket, 0);
stream_set_write_buffer($socket, 0);


これで開いたソケットに、APNSのペイロードを書き込んであげれば良い。


あと、重要なTipsとして、Proxy(apacheだとして)に
AllowCONNECTディレクティブで2195ポートを開ける必要があったりする。
このとき、(IP制限とかで)適切な制限を設けないと、APNSの踏み台になっちゃうので注意。