/** * 发布一条消息 * @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; }