<?php
class MqService {
protected static $instanceArr = array();
/** @var AMQPConnection $connectObj */
protected $connectObj;
/** @var AMQPChannel $channelObj */
protected $channelObj;
/** @var AMQPExchange $exchangeObj */
protected $exchangeObj;
/** @var AMQPQueue $queueObj */
protected $queueObj;
protected $ip;
protected $configName;
protected $configInfoArr;
public function getConfigName() {
return $this->configName;
}
protected function setConfigName($configName) {
$this->configName = $configName;
}
public function getConnectObj() {
return $this->connectObj;
}
protected function setConnectObj($connectObj) {
$this->connectObj = $connectObj;
}
public function getChannelObj() {
return $this->channelObj;
}
protected function setChannelObj($channelObj) {
$this->channelObj = $channelObj;
}
public function getExchangeObj() {
return $this->exchangeObj;
}
protected function setExchangeObj($exchangeObj) {
$this->exchangeObj = $exchangeObj;
}
public function getQueueObj() {
return $this->queueObj;
}
protected function setQueueObj($queueObj) {
$this->queueObj = $queueObj;
}
public function getIp() {
return $this->ip;
}
protected function setIp($ip) {
$this->ip = $ip;
}
public function getConfigInfoArr() {
return $this->configInfoArr;
}
protected function setConfigInfoArr($configInfoArr) {
$this->configInfoArr = is_array($configInfoArr) ? $configInfoArr : array();
}
public function __construct($configName='') {
try {
$this->setIp(CommonModel::getServerIp());
$this->setConfigName($configName);
$configInfoArr = $this->checkConfig();
$this->setConfigInfoArr($configInfoArr);
if (!isset(self::$instanceArr[$this->configName]) || !is_object(self::$instanceArr[$this->configName]['connectObj']) || (false === self::$instanceArr[$this->configName]['connectObj']->isConnected())) {
self::$instanceArr[$this->configName] = $this->connect();
}
else {
$this->setConnectObj(self::$instanceArr[$this->configName]['connectObj']);
$this->setChannelObj(self::$instanceArr[$this->configName]['channelObj']);
$this->setExchangeObj(self::$instanceArr[$this->configName]['exchangeObj']);
$this->setQueueObj(self::$instanceArr[$this->configName]['queueObj']);
}
}
catch (Exception $e) {
throw $e;
}
}
/**
* 发送消息到队列
* @param string $content
* @throws Exception
*
*/
public function sendMessage($content) {
try {
$resultArr = array('status'=>true, 'code'=>SysConst::SUCCESS, 'info'=>'', 'detail'=>'');
$content = trim($content);
$result = $this->exchangeObj->publish($content, $this->configInfoArr['routeKey']);
if ($result === false) {
$errorLogDataArr = array(
'result[false]',
'config['.json_encode($this->configInfoArr, JSON_UNESCAPED_UNICODE).']',
'content['.$content.']',
);
$code = SysConst::ERR_FAILED;
$message = str_replace('__INFO__', $this->configName.'消息队列发送', SysConst::$infoArr[$code]);
throw new Exception($message, $code, new Exception(json_encode($errorLogDataArr), $code));
}
}
catch (Exception $e) {
$resultArr['status'] = false;
$resultArr['code'] = $e->getCode();
$resultArr['info'] = $e->getMessage();
$resultArr['detail'] = $e->getMessage();
}
return $resultArr;
}
/**
* 从消息队列接收消息
* @param string $content
* @throws Exception
*
*/
public function receiveMessage() {
try {
$resultArr = array('status'=>true, 'code'=>SysConst::SUCCESS, 'info'=>'', 'detail'=>'');
$envelopeObj = $this->queueObj->get(AMQP_AUTOACK);
$info = '';
if ($envelopeObj === false) {
$errorLogDataArr = array(
'envelopeObj[false]',
);
$code = SysConst::ERR_EMPTY;
$message = '消息队列已为空';
throw new Exception($message, $code, new Exception(json_encode($errorLogDataArr), $code));
}
$info = $envelopeObj->getBody();
$resultArr['info'] = $info;
$resultArr['detail'] = $info;
}
catch (Exception $e) {
$resultArr['status'] = false;
$resultArr['code'] = $e->getCode();
$resultArr['info'] = $e->getMessage();
$resultArr['detail'] = $e->getMessage();
}
return $resultArr;
}
/**
* 返回消息队列数量
* @param string $content
* @throws Exception
*
*/
public function getQueueTotalNumber() {
try {
$resultArr = array('status'=>true, 'code'=>SysConst::SUCCESS, 'info'=>'', 'detail'=>'');
$totalNumber = $this->queueObj->declareQueue();
$resultArr['info'] = $totalNumber;
$resultArr['detail'] = $info;
}
catch (Exception $e) {
$resultArr['status'] = false;
$resultArr['code'] = $e->getCode();
$resultArr['info'] = $e->getMessage();
$resultArr['detail'] = $e->getMessage();
}
return $resultArr;
}
/**
* 清除消息队列
* @param string $content
* @throws Exception
*
*/
public function purgeQueue() {
try {
$resultArr = array('status'=>true, 'code'=>SysConst::SUCCESS, 'info'=>'', 'detail'=>'');
$result = $this->queueObj->purge();
$resultArr['info'] = $result;
$resultArr['detail'] = $info;
}
catch (Exception $e) {
$resultArr['status'] = false;
$resultArr['code'] = $e->getCode();
$resultArr['info'] = $e->getMessage();
$resultArr['detail'] = $e->getMessage();
}
return $resultArr;
}
/**
* 配置校验
* @return array
* @throws Exception
*/
protected function checkConfig() {
try {
$configName = strtoupper(trim($this->getConfigName()));
$serverIp = $this->getIp();
$configInfoArr = array();
$moduleName = Yaf_Dispatcher::getInstance()->getRequest()->getModuleName();
$configArr = Yaf_Registry::get($moduleName.'ConfigArr');
$mqConfigArr = Yaf_Registry::get($moduleName.'MqConfigArr');
$env = $configArr[$serverIp]['env'];
if (!isset($configArr[$serverIp])) {
$errorLogDataArr = array(
'serverIp['.$serverIp.']',
'config['.json_encode($configArr, JSON_UNESCAPED_UNICODE).']',
);
$code = SysConst::ERR_DATA_NOT_FOUND;
$message = str_replace('__INFO__', 'serverIp['.$serverIp.']对应的MQ的配置信息', SysConst::$infoArr[$code]);
throw new Exception($message, $code, new Exception(json_encode($errorLogDataArr), $code));
}
if ('' === $configName) {
$configName = array_search(DEFAULT_VALUE, $configArr[$serverIp][MQ_INDEX]);
}
else {
$configName = isset($configArr[$serverIp][MQ_INDEX][$configName]) ? $configName : false;
}
if (false === $configName) {
$errorLogDataArr = array(
'serverIp['.$serverIp.']',
'config['.json_encode($configArr, JSON_UNESCAPED_UNICODE).']',
);
$code = SysConst::ERR_DATA_NOT_FOUND;
$message = str_replace('__INFO__', 'serverIp['.$serverIp.']对应的MQ的配置信息', SysConst::$infoArr[$code]);
throw new Exception($message, $code, new Exception(json_encode($errorLogDataArr), $code));
}
$configInfoArr = isset($mqConfigArr[$env][$configName]) ? $mqConfigArr[$env][$configName] : array();
if (empty($configInfoArr)) {
$errorLogDataArr = array(
'serverIp['.$serverIp.']',
'config['.json_encode($configArr, JSON_UNESCAPED_UNICODE).']',
);
$code = SysConst::ERR_DATA_NOT_FOUND;
$message = str_replace('__INFO__', 'serverIp['.$serverIp.']对应的MQ的配置信息', SysConst::$infoArr[$code]);
throw new Exception($message, $code, new Exception(json_encode($errorLogDataArr), $code));
}
$this->setConfigName($configName);
return $configInfoArr;
}
catch (Exception $e) {
throw $e;
}
}
/**
* 创建连接
* @throws Exception
*
*/
protected function connect() {
try {
$this->createConnectObj();
$this->createChannelObj();
$this->createExchangeObj();
$this->createQueueObj();
return array(
'connectObj' => $this->connectObj,
'channelObj' => $this->channelObj,
'exchangeObj' => $this->exchangeObj,
'queueObj' => $this->queueObj,
);
}
catch (Exception $e) {
throw $e;
}
}
/**
* 创建连接对象
* @throws Exception
*
*/
protected function createConnectObj() {
try {
$configArr = array(
'host' => $this->configInfoArr['host'],
'port' => $this->configInfoArr['port'],
'vhost' => $this->configInfoArr['vhost'],
'login' => $this->configInfoArr['username'],
'password' => $this->configInfoArr['password'],
);
$connectObj = new AMQPConnection($configArr);
if (!is_object($connectObj)) {
$errorLogDataArr = array(
'configArr['.json_encode($configArr, JSON_UNESCAPED_UNICODE).']',
);
$code = SysConst::ERR_NOT_INIT;
$message = str_replace('__INFO__', 'MQ对象', SysConst::$infoArr[$code]);
throw new Exception($message, $code, new Exception(json_encode($errorLogDataArr), $code));
}
$isConnected = $connectObj->connect();
if ($isConnected === false) {
$errorLogDataArr = array(
'configArr['.json_encode($configArr, JSON_ERROR_NONE).']',
);
$code = SysConst::ERR_NOT_CONNECTED;
$message = str_replace('__INFO__', 'MQ对象', SysConst::$infoArr[$code]);
throw new Exception($message, $code, new Exception(json_encode($errorLogDataArr), $code));
}
$this->setConnectObj($connectObj);
}
catch (Exception $e) {
throw $e;
}
}
/**
* 创建通道对象
* @throws Exception
*
*/
protected function createChannelObj() {
try {
$channelObj = new AMQPChannel($this->connectObj);
if (!is_object($channelObj)) {
$errorLogDataArr = array(
'channelObj['.(is_null($channelObj) ? 'null' : $channelObj).']',
);
$code = SysConst::ERR_NOT_INIT;
$message = str_replace('__INFO__', '通道对象', SysConst::$infoArr[$code]);
throw new Exception($message, $code, new Exception(json_encode($errorLogDataArr), $code));
}
$this->setChannelObj($channelObj);
}
catch (Exception $e) {
throw $e;
}
}
/**
* 创建交换机对象
* @throws Exception
*
*/
protected function createExchangeObj() {
try {
$exchangeObj = new AMQPExchange($this->channelObj);
if (!is_object($exchangeObj)) {
$errorLogDataArr = array(
'exchangeObj['.(is_null($exchangeObj) ? 'null' : $exchangeObj).']',
);
$code = SysConst::ERR_NOT_INIT;
$message = str_replace('__INFO__', '交换机对象', SysConst::$infoArr[$code]);
throw new Exception($message, $code, new Exception(json_encode($errorLogDataArr), $code));
}
$exchangeObj->setName($this->configInfoArr['exchangeName']);
$exchangeObj->setType($this->configInfoArr['exchangeType']);
$exchangeObj->setFlags($this->configInfoArr['flags']);
$exchangeObj->declareExchange();
$this->setExchangeObj($exchangeObj);
}
catch (Exception $e) {
throw $e;
}
}
/**
* 创建队列对象
* @throws Exception
*
*/
protected function createQueueObj() {
try {
$queueObj = new AMQPQueue($this->channelObj);
if (!is_object($queueObj)) {
$errorLogDataArr = array(
'queueObj['.(is_null($queueObj) ? 'null' : $queueObj).']',
);
$code = SysConst::ERR_NOT_INIT;
$message = str_replace('__INFO__', '队列对象', SysConst::$infoArr[$code]);
throw new Exception($message, $code, new Exception(json_encode($errorLogDataArr), $code));
}
$queueObj->setName($this->configInfoArr['queueName']);
$queueObj->setFlags($this->configInfoArr['flags']);
$queueObj->declareQueue();
$queueObj->bind($this->configInfoArr['exchangeName'], $this->configInfoArr['routeKey']);
$this->setQueueObj($queueObj);
}
catch (Exception $e) {
throw $e;
}
}
}