<?php /** * ApplePush 蘋果訊息推送公用類 */ class ApplePush { const STATUS_CODE_INTERNAL_ERROR = 999; const ERROR_RESPONSE_SIZE = 6; const ERROR_RESPONSE_COMMAND = 8; protected $_errorResponseMessages = array( 0 => 'No errors encountered', 1 => 'Processing error', 2 => 'Missing device token', 3 => 'Missing topic', 4 => 'Missing payload', 5 => 'Invalid token size', 6 => 'Invalid topic size', 7 => 'Invalid payload size', 8 => 'Invalid token', self::STATUS_CODE_INTERNAL_ERROR => 'Internal error' ); /** * APNS server url * * @var string */ protected $apns_url = 'ssl://gateway.push.apple.com:2195'; //沙箱地址:ssl://gateway.sandbox.push.apple.com:2195 /** * 推送資料 * * @var string */ private $payload_json; /** * 資料流對象 * * @var mixed */ private $fp; /** * 設定APNS地址 * * @param string $url */ public function setApnsUrl($url) { if (empty($url)) { return false; } else { $this->apns_url = $url; } return true; } /** * 設定推送的訊息 * * @param string $body */ public function setBody($body) { if (empty($body)) { return false; } else { $this->payload_json = json_encode($body); } return true; } /** * Open 開啟APNS伺服器串連 * * @param string $pem 認證 * @param string $passphrase 認證密鑰 */ public function open($pem, $passphrase) { if (empty($pem)) { return false; } if (empty($passphrase)) { return false; } $ctx = stream_context_create(); stream_context_set_option($ctx, 'ssl', 'local_cert', $pem); stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase); $fp = stream_socket_client($this->apns_url, $err, $errstr, 60, STREAM_CLIENT_CONNECT, $ctx); if (!$fp) { return false; } $this->fp = $fp; return true; } /** * Send 推送 * * @param string $token */ public function send($token, $id) { $msg = pack('CNNnH*', 1, $id, 864000, 32, $token) . pack('n', strlen($this->payload_json)) . $this->payload_json; // Send it to the server $result = fwrite($this->fp, $msg, strlen($msg)); return $result; } public function readErrMsg() { $errInfo = @fread($this->fp, self::ERROR_RESPONSE_SIZE); if ($errInfo === false || strlen($errInfo) != self::ERROR_RESPONSE_SIZE) { return true; } $errInfo = $this->parseErrMsg($errInfo); if (!is_array($errInfo) || empty($errInfo)) { return true; } if (!isset($errInfo['command'], $errInfo['statusCode'], $errInfo['identifier'])) { return true; } if ($errInfo['command'] != self::ERROR_RESPONSE_COMMAND) { return true; } $errInfo['timeline'] = time(); $errInfo['statusMessage'] = 'None (unknown)'; $errInfo['errorIdentifier'] = $errInfo['identifier']; if (isset($this->_aErrorResponseMessages[$errInfo['statusCode']])) { $errInfo['statusMessage'] = $this->_errorResponseMessages[$errInfo['statusCode']]; } return $errInfo; } protected function parseErrMsg($errorMessage) { return unpack('Ccommand/CstatusCode/Nidentifier', $errorMessage); } /** * Close APNS server 關閉APNS伺服器串連 * */ public function close() { // Close the connection to the server fclose($this->fp); return true; } } ?> |