1. URL是不一样的,端口是2196
2. 使用同样的Certificate,建立安全连接,接受数据,直到数据不存在,类似table select操作
3.每条纪录是一个token,server然后要删除这些device token纪录
Access to the feedback service takes place through a binary interface similar to that used for sending push notifications. You access the production feedback service via feedback.push.apple.com, port 2196; you access the sandbox feedback service viafeedback.sandbox.push.apple.com, port 2196. As with the binary interface for push notifications, you must use TLS (or SSL) to establish a secured communications channel. The SSL certificate required for these connections is the same one that is provisioned for sending notifications. To establish a trusted provider identity, you should present this certificate to APNs at connection time using peer-to-peer authentication.
Once you are connected, transmission begins immediately; you do not need to send any command to APNs. Begin reading the stream written by the feedback service until there is no more data to read. The received data is in tuples having the following format:
Figure 5-4 Binary format of a feedback tuple
http://code.google.com/p/apns-php/
Features
Autoload system, explicitly include only Autoload.php and all classes are loaded on-demand.
Message class, to build a notification payload.
Push class, to push one or more messages to Apple Push Notification service.
Feedback class, to query the Apple Feedback service to get the list of broken device tokens.
Push Server class, to create a Push Server with one or more (forked) processes reading from a common message queue.
Log class/interface, to log to standard output or for custom logging purpose.
Objective-C Demo Project with not-running, running in foreground and running in background application state support.
Classes hierarchy
看一下feedback的代码:
public function receive()
{
$nFeedbackTupleLen = self::TIME_BINARY_SIZE + self::TOKEN_LENGTH_BINARY_SIZE + self::DEVICE_BINARY_SIZE;
$this->_aFeedback = array();
$sBuffer = '';
while (!feof($this->_hSocket)) {
$this->_log('INFO: Reading...');
$sBuffer .= $sCurrBuffer = fread($this->_hSocket, 8192);
$nCurrBufferLen = strlen($sCurrBuffer);
if ($nCurrBufferLen > 0) {
$this->_log("INFO: {$nCurrBufferLen} bytes read.");
}
unset($sCurrBuffer, $nCurrBufferLen);
$nBufferLen = strlen($sBuffer);
if ($nBufferLen >= $nFeedbackTupleLen) {
$nFeedbackTuples = floor($nBufferLen / $nFeedbackTupleLen);
for ($i = 0; $i < $nFeedbackTuples; $i++) {
$sFeedbackTuple = substr($sBuffer, 0, $nFeedbackTupleLen);
$sBuffer = substr($sBuffer, $nFeedbackTupleLen);
$this->_aFeedback[] = $aFeedback = $this->_parseBinaryTuple($sFeedbackTuple);
$this->_log(sprintf("INFO: New feedback tuple: timestamp=%d (%s), tokenLength=%d, deviceToken=%s.",
$aFeedback['timestamp'], date('Y-m-d H:i:s', $aFeedback['timestamp']),
$aFeedback['tokenLength'], $aFeedback['deviceToken']
));
unset($aFeedback);
}
}
$read = array($this->_hSocket);
$null = NULL;
$nChangedStreams = stream_select($read, $null, $null, 0, $this->_nSocketSelectTimeout);
if ($nChangedStreams === false) {
$this->_log('WARNING: Unable to wait for a stream availability.');
break;
}
}
return $this->_aFeedback;
}
/**
* Parses binary tuples.
*
* @param $sBinaryTuple @type string A binary tuple to parse.
* @return @type array Array with timestamp, tokenLength and deviceToken keys.
*/
protected function _parseBinaryTuple($sBinaryTuple)
{
return unpack('Ntimestamp/ntokenLength/H*deviceToken', $sBinaryTuple);
}