/**
  * Data decoding, according to related IETF draft
  *
  * @see http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-10#page-16
  */
 protected function _dataDecode()
 {
     //参考 http://blog.csdn.net/fenglibing/article/details/6852497
     //这里仅仅处理最基本的
     $encodedData =& $this->webSocketSession->buf;
     // 至少有2个字节的头
     while (($buflen = strlen($encodedData)) >= 2) {
         $len = 0;
         $isMasked = (bool) (ord($encodedData[1]) >> 7);
         $opcode = ord($encodedData[0]) & 15;
         $dataLength = ord($encodedData[1]) & 127;
         $len += 2;
         if ($dataLength === 126) {
             $extDataLength = hexdec(sprintf('%02x%02x', ord($encodedData[2]), ord($encodedData[3])));
             $len += 2;
         } else {
             if ($dataLength === 127) {
                 $extDataLength = hexdec(sprintf('%02x%02x%02x%02x%02x%02x%02x%02x', ord($encodedData[2]), ord($encodedData[3]), ord($encodedData[4]), ord($encodedData[5]), ord($encodedData[6]), ord($encodedData[7]), ord($encodedData[8]), ord($encodedData[9])));
                 $len += 8;
             } else {
                 $extDataLength = $dataLength;
             }
         }
         if (webSocketSession::maxPacketSize <= $extDataLength) {
             // Too big packet
             $this->webSocketSession->close();
             return;
         }
         if ($isMasked) {
             $maskingKey = Utils::binarySubstr($encodedData, $len, 4);
             $len += 4;
         }
         if ($extDataLength + $len > strlen($encodedData)) {
             //没有出现包
             // not enough data yet
             return;
         }
         $data = Utils::binarySubstr($encodedData, $len, $extDataLength);
         //这里用的引用,所以会处理掉 socketSession->buf
         $encodedData = Utils::binarySubstr($encodedData, $len + $extDataLength);
         if ($opcode === self::CLOSE) {
             //客户端主动关闭连接
             $this->webSocketSession->close();
             return;
         }
         if ($opcode === self::PING) {
             $this->sendFrame('', 'PONG');
             continue;
         }
         if ($opcode === self::PONG) {
             //todo: 收到 pong 包,不做任何事情,以后应该更新最后的连接时间
             daemon::log(get_class($this) . '::' . __METHOD__ . ' : receive PONG packet. ' . $this->webSocketSession->addr);
             continue;
         }
         if ($isMasked) {
             $unmaskingFunc = function ($data, $mask) {
                 for ($i = 0, $l = strlen($data); $i < $l; $i++) {
                     // Avoid storing a new copy of $data...
                     $data[$i] = $data[$i] ^ $mask[$i % 4];
                 }
                 return $data;
             };
             $this->webSocketSession->onFrame($unmaskingFunc($data, $maskingKey), $opcode);
         } else {
             $this->webSocketSession->onFrame($data, $opcode);
         }
     }
 }