/**
  * 发布一条消息
  * @param BigpipeMessagePackage $msg_pacakge
  * @return BigpipePubResult on success or false on failure
  */
 public function send($msg_package)
 {
     if (!$this->_is_started) {
         BigpipeLog::warning("[connection is not established][pipelet:%d]", $this->_pipelet_id);
         return false;
     }
     // 发送CONNECT
     $cmd = new BStompSendFrame();
     if (!$msg_package->store($cmd->message_body)) {
         // 包错误,不用考虑failover了
         BigpipeLog::warning("[fail to store message body]");
         return false;
     }
     if (true === $this->_last_send_ok) {
         // 当上次发送成功才增加session mesage id
         // 否则message id不变,防止重复发送
         $this->_session_msg_id++;
     }
     $cmd->destination = $this->_get_stripe_name();
     // echo "[stripe name][$cmd->destination]<br>";
     $cmd->no_dedupe = $this->_no_dedupe;
     $cmd->session_id = $this->_session_id;
     $cmd->session_message_id = $this->_session_msg_id;
     $cmd->receipt_id = isset($this->unittest) ? 'fake-receipt-id' : BigpipeUtilities::gen_receipt_id();
     if ($this->_enable_checksum) {
         // 发送message包校验
         $cmd->last_checksum = $this->_last_sign;
         $sign = creat_sign_mds64($cmd->message_body);
         $cmd->cur_checksum = $sign[2];
         // 注意函数返回值
         $this->_last_sign = $cmd->cur_checksum;
     }
     // 进入发送流程,
     // 发送失败则进入failover流程,直到failover失败。
     $send_result = false;
     do {
         if (false === $this->_stomp_adapter->send($cmd)) {
             BigpipeLog::warning("[send message error][session:%s][session_msg_id:%u]", $cmd->session_id, $cmd->session_message_id);
             continue;
         }
         $send_result = $this->_check_ack($cmd->receipt_id, $send_result);
         if (false === $send_result) {
             // ACK失败
             // 不用考虑BMQ_E_COMMAND_DUPLICATEMSG, 去重在broker做,
             // 用户不会收到duplicate返回.
             BigpipeLog::warning("[send message ack error][session:%s][session_msg_id:%u]", $cmd->session_id, $cmd->session_message_id);
             continue;
         } else {
             BigpipeLog::notice("[send message success][pipelet:%u][session:%s][session_msg_id:%u]", $this->_pipelet_id, $cmd->session_id, $cmd->session_message_id);
             break;
             // 发布成功
         }
     } while ($this->_failover());
     if (false !== $send_result) {
         $this->_active();
         // 清理failover状态
     } else {
         $this->_last_send_ok = false;
     }
     return $send_result;
 }
 private function _gen_recv_response()
 {
     $topic_id = 65535;
     $bad_topic_id = 0;
     $pkg = new BigpipeMessagePackage();
     $msg = 'This is a test case';
     $pkg->push($msg);
     $msg_body = null;
     $pkg->store($msg_body);
     $sign = creat_sign_mds64($msg_body);
     $frame = new BStompMessageFrame();
     $frame->priority = 10;
     $frame->persistent = 1;
     $frame->no_dedupe = 1;
     $frame->timeout = BigpipeUtilities::get_time_us();
     $frame->destination = 'cluster-for-unittest';
     $frame->session_id = BigpipeUtilities::get_uid();
     $frame->subscribe_id = BigpipeUtilities::get_uid();
     $frame->receipt_id = BigpipeUtilities::gen_receipt_id();
     $frame->session_message_id = BigpipeUtilities::get_uid();
     $frame->topic_message_id = $topic_id;
     $frame->global_message_id = 76248;
     $frame->cur_checksum = $sign[2];
     $frame->last_checksum = 0;
     $frame->message_body = $msg_body;
     $frame->store();
     $good = $frame->buffer();
     // topic message id ´íÎóµÄcase
     $frame->topic_message_id = $bad_topic_id;
     $frame->store();
     $bad_topic = $frame->buffer();
     // message body ´íÎóµÄcase
     $frame->topic_message_id = $topic_id;
     $frame->message_body = '';
     $frame->store();
     $bad_body = $frame->buffer();
     // checksum´íÎóµÄcase
     $frame->message_body = $msg_body;
     $frame->cur_checksum = 201;
     $frame->store();
     $bad_checksum = $frame->buffer();
     // ´´ÔìÒ»¸öerrorµÄ°ü
     $err_pkg = '1';
     $frame->message_body = $err_pkg;
     $err_sign = creat_sign_mds64($err_pkg);
     $frame->cur_checksum = $err_sign[2];
     $frame->store();
     $bad_pkg = $frame->buffer();
     // ´´ÔìÒ»¸öpop errorµÄ°ü
     $frame->message_body = pack("L2", 1, 5);
     // ÕâÊÇÒ»¸ö³¤¶ÈΪ5£¬µ«ÊÇûÓÐÊý¾ÝµÄ»µ°ü
     $empty_sign = creat_sign_mds64($frame->message_body);
     $frame->cur_checksum = $empty_sign[2];
     $frame->store();
     $empty_pkg = $frame->buffer();
     $res_arr = array('good' => $good, 'bad_topic' => $bad_topic, 'bad_body' => $bad_body, 'bad_checksum' => $bad_checksum, 'bad_pkg' => $bad_pkg, 'empty_pkg' => $empty_pkg);
     return $res_arr;
 }
 /**
  * 取消订阅
  */
 private function _unsubscribe()
 {
     if (!$this->_is_subscribed) {
         return true;
         // 取消成功
     }
     // 填充取消订阅包
     $cmd = new BStompUnsubscribeFrame();
     $cmd->destination = $this->_stripe['stripe_name'];
     // $cmd->subscribe_id = null; 目前无用
     $cmd->receipt_id = isset($this->unittest) ? 'unittest-receipt-id' : BigpipeUtilities::gen_receipt_id();
     if (!$this->_stomp_adapter->send($cmd)) {
         BigpipeLog::warning('[%s:%u][%s][send error]', __FILE__, __LINE__, __FUNCTION__);
         return false;
     }
     // 接收RECEIPT
     $res_body = $this->_stomp_adapter->receive();
     if (null === $res_body) {
         BigpipeLog::warning('[%s:%u][%s][receive error]', __FILE__, __LINE__, __FUNCTION__);
         return false;
     }
     // parse RECEIPT
     $ack = new BStompReceiptFrame();
     if (!$ack->load($res_body)) {
         BigpipeLog::warning('[%s:%u][%s][load receipt error][cmd_type:%d][err_msg:%s]', __FILE__, __LINE__, __FUNCTION__, $ack->command_type, $ack->last_error_message());
         return false;
     }
     // 检查取消订阅是否成功
     if ($ack->receipt_id != $cmd->receipt_id) {
         BigpipeLog::warning('[%s:%u][%s][error receipt id][send:%u][recv:%u]', __FILE__, __LINE__, __FUNCTION__, $cmd->receipt_id, $ack->receipt_id);
         return false;
     }
     $this->_is_subscribed = false;
     return true;
 }