rabbitmq的实现(PHP--简单模式、fanout模式、direct模式、topic模式)

	$this->mq_host, 
				'port'		=>	$this->mq_port1, 
				'user'		=>	$this->mq_user, 
				'password'	=>	$this->mq_passwd, 
				'vhost'		=>	$this->mq_vhost
			],
			[
				'host'		=>	$this->mq_host, 
				'port'		=>	$this->mq_port2, 
				'user'		=>	$this->mq_user, 
				'password'	=>	$this->mq_passwd, 
				'vhost'		=>	$this->mq_vhost
			],
			[
				'host'		=>	$this->mq_host, 
				'port'		=>	$this->mq_port3, 
				'user'		=>	$this->mq_user, 
				'password'	=>	$this->mq_passwd, 
				'vhost'		=>	$this->mq_vhost
			],
		];
		
		$options = [];
		
		$this->connection = AMQPStreamConnection::create_connection($host,$options);
	}
}

BasicConnect.php

 

connection->channel();
		
		/**
		*	name: $queue    队列名称
		*	passive: false  不检查是否存在同名队列(don't check if a queue with the same name exists)
		*	durable: true  服务器重启后队列将无法生存(the queue will not survive server restarts)
		*	exclusive: false 可以通过其他通道访问队列(the queue can be accessed in other channels)
		*	auto_delete: false 一旦通道关闭,队列将不会被删除。(the queue won't be deleted once the channel is closed.)
		*/
		$channel->queue_declare($this->queue, false, true, false, false);

		/**
		*	name: $exchange
		*	type: direct
		*	passive: false
		*	durable: true 服务器重启后交换机将仍存在(the exchange will survive server restarts)
		*	auto_delete: false 一旦频道关闭,将不会删除交换。(the exchange won't be deleted once the channel is closed.)
		*/
		$channel->exchange_declare($this->exchange, AMQPExchangeType::DIRECT, false, true, false);

		$channel->queue_bind($this->queue, $this->exchange);

		# 仅发送1条数据
		// $messageBody = 'it is a simple message';
		// $message = new AMQPMessage($messageBody,['content_type' => 'text/plain', 'delivery_mode' => AMQPMessage::DELIVERY_MODE_PERSISTENT]);
		// $channel->basic_publish($message, $this->exchange);
		
		
		# 发送多条数据(注意,仅第一次创建AMQPMessage对象,其它通过setBody复用前面创建的对象)
		$properties = ['content_type' => 'text/plain', 'delivery_mode' => AMQPMessage::DELIVERY_MODE_PERSISTENT];
		
		for($i=1;$i<10;$i++){
			$messageBody = 'it is a simple message:'.$i;
			
			if( $i == 1){
				$message = new AMQPMessage($messageBody, $properties);
			}else{
				$message->setBody($messageBody);
			}
			
			$channel->basic_publish($message, $this->exchange);
		}

		
		
		$channel->close();
		
		$this->connection->close();
	 
		exit;
	}
}

SimpleProducer.php

connection->channel();
		
		/**
		*	name: $queue    队列名称
		*	passive: false  
		*	durable: true  服务器重启后队列将仍存在(the queue will survive server restarts)
		*	exclusive: false 可以通过其他通道访问队列(the queue can be accessed in other channels)
		*	auto_delete: false 一旦通道关闭,队列将不会被删除。(the queue won't be deleted once the channel is closed.)
		*/
		$channel->queue_declare($this->queue, false, true, false, false);

		/**
		*	name: $exchange
		*	type: direct
		*	passive: false
		*	durable: true 服务器重启后交换机将仍存在(the exchange will survive server restarts)
		*	auto_delete: false 一旦频道关闭,将不会删除交换。(the exchange won't be deleted once the channel is closed.)
		*/
		$channel->exchange_declare($this->exchange, AMQPExchangeType::DIRECT, false, true, false);

		$channel->queue_bind($this->queue, $this->exchange);

		/**
		*	queue: 队列名称,从何处获取消息的队列(Queue from where to get the messages)
		*	consumer_tag: 消费者标识符(Consumer identifier)
		*	no_local: 不接收此消费者发布的消息。(Don't receive messages published by this consumer.)
		*	no_ack: 如果设置为真,则此用户将使用自动确认模式(If set to true, automatic acknowledgement mode will be used by this consumer. See https://www.rabbitmq.com/confirms.html for details.)
		*	exclusive: 请求独占使用者访问,这意味着只有此使用者可以访问队列(Request exclusive consumer access, meaning only this consumer can access the queue)
		*	nowait: 不要等待服务器响应。如果出现错误,服务器将引发通道异常(don't wait for a server response. In case of error the server will raise a channel exception)
		*	callback: 回调函数(A PHP Callback)
		*/
		$channel->basic_consume($this->queue, $consumerTag, false, false, false, false, [new FanoutConsumer1(),'process_message']);

		register_shutdown_function([new FanoutConsumer1(),'shutdown'], $channel, $this->connection);
		
		// 循环,只要通道已注册回调(Loop as long as the channel has callbacks registered)
		while ($channel->is_consuming()) {
			$channel->wait();
		}

		exit;
	}
	
	/**
	 * 回调函数
	 */
	public function process_message($message){
		echo "\n--------\n";
		echo $message->body;
		echo "\n--------\n";

		$message->delivery_info['channel']->basic_ack($message->delivery_info['delivery_tag']);

		// 发送字符串“quit”通知消费者退出。(Send a message with the string "quit" to cancel the consumer.)
		if ($message->body === 'quit') {
			$message->delivery_info['channel']->basic_cancel($message->delivery_info['consumer_tag']);
		}
	}
	
	/**
	 * @param \PhpAmqpLib\Channel\AMQPChannel $channel
	 * @param \PhpAmqpLib\Connection\AbstractConnection $connection
	 */
	public function shutdown($channel, $connection)
	{
		$channel->close();
		$connection->close();
	}
}

SimpleConsumer.php

connection->channel();
	   /**
		*	name: $exchange 交换机名称
		*	type: fanout   交换机类型
		*	passive: false 是否检查存在同名的交换机(don't check is an exchange with the same name exists)
		*	durable: false 服务器重启后销毁交换机(the exchange won't survive server restarts)
		*	auto_delete: true 管道(channel)关闭后将销毁交换机(the exchange will be deleted once the channel is closed.)
		*/
		$channel->exchange_declare($this->exchange, AMQPExchangeType::FANOUT, false, false, true);
		
		$messageBody = 'I am a fanout message';
		
		$message = new AMQPMessage($messageBody, ['content_type' => 'text/plain']);
		
		$res = $channel->basic_publish($message, $this->exchange);
		
		$channel->close();
		
		$this->connection->close();

		exit;
	}
}

FanoutProducer.php

connection->channel();

	   /**
		*	name: $queue    队列名称,在fanout类型的交换机中必须唯一(should be unique in fanout exchange.)
		*	passive: false  不检查是否存在同名队列(don't check if a queue with the same name exists)
		*	durable: false  服务器重启后队列将无法生存(the queue will not survive server restarts)
		*	exclusive: false 队列可能被其他通道访问(the queue might be accessed by other channels)
		*	auto_delete: true 一旦通道关闭,队列将被删除(the queue will be deleted once the channel is closed.)
		*/
		$channel->queue_declare($this->queue, false, false, false, true);

	   /**
		*	name: $exchange 交换机名称
		*	type: fanout   交换机类型
		*	passive: false 是否检查存在同名的交换机(don't check is an exchange with the same name exists)
		*	durable: false 服务器重启后销毁交换机(the exchange won't survive server restarts)
		*	auto_delete: true 管道(channel)关闭后将销毁交换机(the exchange will be deleted once the channel is closed.)
		*/
		$channel->exchange_declare($this->exchange, AMQPExchangeType::FANOUT, false, false, true);

		$channel->queue_bind($this->queue, $this->exchange);

		
		/*
		*	queue: 队列名称,从何处获取消息的队列(Queue from where to get the messages)
		*	consumer_tag: 消费者标识符(Consumer identifier)
		*	no_local: 不接收此消费者发布的消息。(Don't receive messages published by this consumer.)
		*	no_ack: 如果设置为真,则此用户将使用自动确认模式(If set to true, automatic acknowledgement mode will be used by this consumer. See https://www.rabbitmq.com/confirms.html for details.)
		*	exclusive: 请求独占使用者访问,这意味着只有此使用者可以访问队列(Request exclusive consumer access, meaning only this consumer can access the queue)
		*	nowait: 不要等待服务器响应。如果出现错误,服务器将引发通道异常(don't wait for a server response. In case of error the server will raise a channel exception)
		*	callback: 回调函数(A PHP Callback)
		*/

		$channel->basic_consume($this->queue, $consumerTag, false, false, false, false, [new FanoutConsumer1(),'process_message']);

		register_shutdown_function([new FanoutConsumer1(),'shutdown'], $channel, $this->connection);

		// 循环,只要通道已注册回调(Loop as long as the channel has callbacks registered)
		while ($channel->is_consuming()) {
			$channel->wait();
		}

		exit;
	}
	
	/**
	 * 回调函数
	 */
	public function process_message($message){
		echo "\n--------\n";
		echo $message->body;
		echo "\n--------\n";

		$message->delivery_info['channel']->basic_ack($message->delivery_info['delivery_tag']);

		// 发送字符串“quit”通知消费者退出。(Send a message with the string "quit" to cancel the consumer.)
		if ($message->body === 'quit') {
			$message->delivery_info['channel']->basic_cancel($message->delivery_info['consumer_tag']);
		}
	}
	
	/**
	 * @param \PhpAmqpLib\Channel\AMQPChannel $channel
	 * @param \PhpAmqpLib\Connection\AbstractConnection $connection
	 */
	public function shutdown($channel, $connection)
	{
		$channel->close();
		$connection->close();
	}

}

FanoutConsumer1.php

connection->channel();

	   /**
		*	name: $queue    队列名称,在fanout类型的交换机中必须唯一(should be unique in fanout exchange.)
		*	passive: false  不检查是否存在同名队列(don't check if a queue with the same name exists)
		*	durable: false  服务器重启后队列将无法生存(the queue will not survive server restarts)
		*	exclusive: false 队列可能被其他通道访问(the queue might be accessed by other channels)
		*	auto_delete: true 一旦通道关闭,队列将被删除(the queue will be deleted once the channel is closed.)
		*/
		$channel->queue_declare($this->queue, false, false, false, true);

	   /**
		*	name: $exchange 交换机名称
		*	type: fanout   交换机类型
		*	passive: false 是否检查存在同名的交换机(don't check is an exchange with the same name exists)
		*	durable: false 服务器重启后销毁交换机(the exchange won't survive server restarts)
		*	auto_delete: true 管道(channel)关闭后将销毁交换机(the exchange will be deleted once the channel is closed.)
		*/
		$channel->exchange_declare($this->exchange, AMQPExchangeType::FANOUT, false, false, true);

		$channel->queue_bind($this->queue, $this->exchange);

		
		/*
		*	queue: 队列名称,从何处获取消息的队列(Queue from where to get the messages)
		*	consumer_tag: 消费者标识符(Consumer identifier)
		*	no_local: 不接收此消费者发布的消息。(Don't receive messages published by this consumer.)
		*	no_ack: 如果设置为真,则此用户将使用自动确认模式(If set to true, automatic acknowledgement mode will be used by this consumer. See https://www.rabbitmq.com/confirms.html for details.)
		*	exclusive: 请求独占使用者访问,这意味着只有此使用者可以访问队列(Request exclusive consumer access, meaning only this consumer can access the queue)
		*	nowait: 不要等待服务器响应。如果出现错误,服务器将引发通道异常(don't wait for a server response. In case of error the server will raise a channel exception)
		*	callback: 回调函数(A PHP Callback)
		*/

		$channel->basic_consume($this->queue, $consumerTag, false, false, false, false, [new FanoutConsumer1(),'process_message']);

		register_shutdown_function([new FanoutConsumer1(),'shutdown'], $channel, $this->connection);

		// 循环,只要通道已注册回调(Loop as long as the channel has callbacks registered)
		while ($channel->is_consuming()) {
			$channel->wait();
		}

		exit;
	}
	
	/**
	 * 回调函数
	 */
	public function process_message($message){
		echo "\n--------\n";
		echo $message->body;
		echo "\n--------\n";

		$message->delivery_info['channel']->basic_ack($message->delivery_info['delivery_tag']);

		// 发送字符串“quit”通知消费者退出。(Send a message with the string "quit" to cancel the consumer.)
		if ($message->body === 'quit') {
			$message->delivery_info['channel']->basic_cancel($message->delivery_info['consumer_tag']);
		}
	}
	
	/**
	 * @param \PhpAmqpLib\Channel\AMQPChannel $channel
	 * @param \PhpAmqpLib\Connection\AbstractConnection $connection
	 */
	public function shutdown($channel, $connection)
	{
		$channel->close();
		$connection->close();
	}

}

FanoutConsumer2.php

connection->channel();
	   /**
		*	name: $exchange 交换机名称
		*	type: DIRECT   交换机类型
		*	passive: false 是否检查存在同名的交换机(don't check is an exchange with the same name exists)
		*	durable: false 服务器重启后销毁交换机(the exchange won't survive server restarts)
		*	auto_delete: true 管道(channel)关闭后将销毁交换机(the exchange will be deleted once the channel is closed.)
		*/
		$channel->exchange_declare($this->exchange, AMQPExchangeType::DIRECT, false, false, true);
		
		$messageBody = 'I am a direct message';
		
		$message = new AMQPMessage($messageBody, ['content_type' => 'text/plain']);
		
		$channel->basic_publish($message, $this->exchange, 'direct_key1');
		
		$channel->close();
		
		$this->connection->close();

		exit;
	}
}

DirectProducer.php

https://www.jianshu.com/p/fdb195698a5a

https://my.oschina.net/u/3698467/blog/1825316

 

connection->channel();

	   /**
		*	name: $queue    队列名称,在fanout类型的交换机中必须唯一(should be unique in fanout exchange.)
		*	passive: false  不检查是否存在同名队列(don't check if a queue with the same name exists)
		*	durable: false  服务器重启后队列将无法生存(the queue will not survive server restarts)
		*	exclusive: false 队列可能被其他通道访问(the queue might be accessed by other channels)
		*	auto_delete: true 一旦通道关闭,队列将被删除(the queue will be deleted once the channel is closed.)
		*/
		$channel->queue_declare($this->queue, false, false, false, true);

	   /**
		*	name: $exchange 交换机名称
		*	type: DIRECT   交换机类型
		*	passive: false 是否检查存在同名的交换机(don't check is an exchange with the same name exists)
		*	durable: false 服务器重启后销毁交换机(the exchange won't survive server restarts)
		*	auto_delete: true 管道(channel)关闭后将销毁交换机(the exchange will be deleted once the channel is closed.)
		*/
		$channel->exchange_declare($this->exchange, AMQPExchangeType::DIRECT, false, false, true);

		$channel->queue_bind($this->queue, $this->exchange, 'direct_key1');
		
		/*
		*	queue: 队列名称,从何处获取消息的队列(Queue from where to get the messages)
		*	consumer_tag: 消费者标识符(Consumer identifier)
		*	no_local: 不接收此消费者发布的消息。(Don't receive messages published by this consumer.)
		*	no_ack: 如果设置为真,则此用户将使用自动确认模式(If set to true, automatic acknowledgement mode will be used by this consumer. See https://www.rabbitmq.com/confirms.html for details.)
		*	exclusive: 请求独占使用者访问,这意味着只有此使用者可以访问队列(Request exclusive consumer access, meaning only this consumer can access the queue)
		*	nowait: 不要等待服务器响应。如果出现错误,服务器将引发通道异常(don't wait for a server response. In case of error the server will raise a channel exception)
		*	callback: 回调函数(A PHP Callback)
		*/

		$channel->basic_consume($this->queue, $consumerTag, false, false, false, false, [new FanoutConsumer1(),'process_message']);

		register_shutdown_function([new FanoutConsumer1(),'shutdown'], $channel, $this->connection);

		// 循环,只要通道已注册回调(Loop as long as the channel has callbacks registered)
		while ($channel->is_consuming()) {
			$channel->wait();
		}

		exit;
	}
	
	/**
	 * 回调函数
	 */
	public function process_message($message){
		echo "\n--------\n";
		echo $message->body;
		echo "\n--------\n";

		$message->delivery_info['channel']->basic_ack($message->delivery_info['delivery_tag']);

		// 发送字符串“quit”通知消费者退出。(Send a message with the string "quit" to cancel the consumer.)
		if ($message->body === 'quit') {
			$message->delivery_info['channel']->basic_cancel($message->delivery_info['consumer_tag']);
		}
	}
	
	/**
	 * @param \PhpAmqpLib\Channel\AMQPChannel $channel
	 * @param \PhpAmqpLib\Connection\AbstractConnection $connection
	 */
	public function shutdown($channel, $connection)
	{
		$channel->close();
		$connection->close();
	}

}

DirectConsumer1.php

connection->channel();
	   /**
		*	name: $exchange 交换机名称
		*	type: TOPIC   交换机类型
		*	passive: false 是否检查存在同名的交换机(don't check is an exchange with the same name exists)
		*	durable: false 服务器重启后销毁交换机(the exchange won't survive server restarts)
		*	auto_delete: true 管道(channel)关闭后将销毁交换机(the exchange will be deleted once the channel is closed.)
		*/
		$channel->exchange_declare($this->exchange, AMQPExchangeType::TOPIC, false, false, true);
		
		$messageBody = 'I am a TOPIC message';
		
		$message = new AMQPMessage($messageBody, ['content_type' => 'text/plain']);
		
		$res = $channel->basic_publish($message, $this->exchange, 'key.1.2');#routing_key设置为key.1.2,只有TopicConsumer2{'key.#'}消费者能收到
		#$res = $channel->basic_publish($message, $this->exchange, 'key.1');#routing_key设置为key.1,TopicConsumer1{'key.*'}和TopicConsumer2{'key.#'}消费者都可以收到
		
		$channel->close();
		
		$this->connection->close();

		exit;
	}
}

TopicProducer.php

*(星号)可以代替一个任意标识符 ;#(井号)可以代替零个或多个标识符。

https://blog.csdn.net/a491857321/article/details/50616323  (JAVA实现)

connection->channel();

	   /**
		*	name: $queue    队列名称,在fanout类型的交换机中必须唯一(should be unique in fanout exchange.)
		*	passive: false  不检查是否存在同名队列(don't check if a queue with the same name exists)
		*	durable: false  服务器重启后队列将无法生存(the queue will not survive server restarts)
		*	exclusive: false 队列可能被其他通道访问(the queue might be accessed by other channels)
		*	auto_delete: true 一旦通道关闭,队列将被删除(the queue will be deleted once the channel is closed.)
		*/
		$channel->queue_declare($this->queue, false, false, false, true);

	   /**
		*	name: $exchange 交换机名称
		*	type: TOPIC   交换机类型
		*	passive: false 是否检查存在同名的交换机(don't check is an exchange with the same name exists)
		*	durable: false 服务器重启后销毁交换机(the exchange won't survive server restarts)
		*	auto_delete: true 管道(channel)关闭后将销毁交换机(the exchange will be deleted once the channel is closed.)
		*/
		$channel->exchange_declare($this->exchange, AMQPExchangeType::TOPIC, false, false, true);

		$channel->queue_bind($this->queue, $this->exchange, 'key.*');

		
		/*
		*	queue: 队列名称,从何处获取消息的队列(Queue from where to get the messages)
		*	consumer_tag: 消费者标识符(Consumer identifier)
		*	no_local: 不接收此消费者发布的消息。(Don't receive messages published by this consumer.)
		*	no_ack: 如果设置为真,则此用户将使用自动确认模式(If set to true, automatic acknowledgement mode will be used by this consumer. See https://www.rabbitmq.com/confirms.html for details.)
		*	exclusive: 请求独占使用者访问,这意味着只有此使用者可以访问队列(Request exclusive consumer access, meaning only this consumer can access the queue)
		*	nowait: 不要等待服务器响应。如果出现错误,服务器将引发通道异常(don't wait for a server response. In case of error the server will raise a channel exception)
		*	callback: 回调函数(A PHP Callback)
		*/

		$channel->basic_consume($this->queue, $consumerTag, false, false, false, false, [new FanoutConsumer1(),'process_message']);

		register_shutdown_function([new FanoutConsumer1(),'shutdown'], $channel, $this->connection);

		// 循环,只要通道已注册回调(Loop as long as the channel has callbacks registered)
		while ($channel->is_consuming()) {
			$channel->wait();
		}

		exit;
	}
	
	/**
	 * 回调函数
	 */
	public function process_message($message){
		echo "\n--------\n";
		echo $message->body;
		echo "\n--------\n";

		$message->delivery_info['channel']->basic_ack($message->delivery_info['delivery_tag']);

		// 发送字符串“quit”通知消费者退出。(Send a message with the string "quit" to cancel the consumer.)
		if ($message->body === 'quit') {
			$message->delivery_info['channel']->basic_cancel($message->delivery_info['consumer_tag']);
		}
	}
	
	/**
	 * @param \PhpAmqpLib\Channel\AMQPChannel $channel
	 * @param \PhpAmqpLib\Connection\AbstractConnection $connection
	 */
	public function shutdown($channel, $connection)
	{
		$channel->close();
		$connection->close();
	}

}

TopicConsumer1.php

connection->channel();

	   /**
		*	name: $queue    队列名称,在fanout类型的交换机中必须唯一(should be unique in fanout exchange.)
		*	passive: false  不检查是否存在同名队列(don't check if a queue with the same name exists)
		*	durable: false  服务器重启后队列将无法生存(the queue will not survive server restarts)
		*	exclusive: false 队列可能被其他通道访问(the queue might be accessed by other channels)
		*	auto_delete: true 一旦通道关闭,队列将被删除(the queue will be deleted once the channel is closed.)
		*/
		$channel->queue_declare($this->queue, false, false, false, true);

	   /**
		*	name: $exchange 交换机名称
		*	type: TOPIC   交换机类型
		*	passive: false 是否检查存在同名的交换机(don't check is an exchange with the same name exists)
		*	durable: false 服务器重启后销毁交换机(the exchange won't survive server restarts)
		*	auto_delete: true 管道(channel)关闭后将销毁交换机(the exchange will be deleted once the channel is closed.)
		*/
		$channel->exchange_declare($this->exchange, AMQPExchangeType::TOPIC, false, false, true);

		$channel->queue_bind($this->queue, $this->exchange, 'key.#');

		
		/*
		*	queue: 队列名称,从何处获取消息的队列(Queue from where to get the messages)
		*	consumer_tag: 消费者标识符(Consumer identifier)
		*	no_local: 不接收此消费者发布的消息。(Don't receive messages published by this consumer.)
		*	no_ack: 如果设置为真,则此用户将使用自动确认模式(If set to true, automatic acknowledgement mode will be used by this consumer. See https://www.rabbitmq.com/confirms.html for details.)
		*	exclusive: 请求独占使用者访问,这意味着只有此使用者可以访问队列(Request exclusive consumer access, meaning only this consumer can access the queue)
		*	nowait: 不要等待服务器响应。如果出现错误,服务器将引发通道异常(don't wait for a server response. In case of error the server will raise a channel exception)
		*	callback: 回调函数(A PHP Callback)
		*/

		$channel->basic_consume($this->queue, $consumerTag, false, false, false, false, [new FanoutConsumer1(),'process_message']);

		register_shutdown_function([new FanoutConsumer1(),'shutdown'], $channel, $this->connection);

		// 循环,只要通道已注册回调(Loop as long as the channel has callbacks registered)
		while ($channel->is_consuming()) {
			$channel->wait();
		}

		exit;
	}
	
	/**
	 * 回调函数
	 */
	public function process_message($message){
		echo "\n--------\n";
		echo $message->body;
		echo "\n--------\n";

		$message->delivery_info['channel']->basic_ack($message->delivery_info['delivery_tag']);

		// 发送字符串“quit”通知消费者退出。(Send a message with the string "quit" to cancel the consumer.)
		if ($message->body === 'quit') {
			$message->delivery_info['channel']->basic_cancel($message->delivery_info['consumer_tag']);
		}
	}
	
	/**
	 * @param \PhpAmqpLib\Channel\AMQPChannel $channel
	 * @param \PhpAmqpLib\Connection\AbstractConnection $connection
	 */
	public function shutdown($channel, $connection)
	{
		$channel->close();
		$connection->close();
	}

}

TopicConsumer2.php

你可能感兴趣的:(php,rabbitmq,rabbitmq,php)