_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); } }