SlideShare una empresa de Scribd logo
1 de 76
Descargar para leer sin conexión
PHP, RabbitMQ, and You
#mwphp14 #rabbitmq @jasonlotito
MidwestPHP 2014 - RabbitMQ
What will we be covering?
1. What is RabbitMQ
2. Technology Overview
3. Publishers
4. Consumers
5. Exchanges
6. Queues
7. Bindings
8. Carrot to make things easy
9. Publish events from the web
10.Multiple consumers
11.Management UI Publishing
12.Consumers Publishing
PHP, RabbitMQ, and You
#mwphp14 #rabbitmq @jasonlotito
Jason Lotito
Senior Architect @ MeetMe
@jasonlotito.com
github.com/jasonlotito@gmail.com
!
Senior Architect means people can blame
me when things don’t work as expected.
When things work, it’s because they
worked around my code.
Who has worked with
RabbitMQ in production?
Raise your hands. The only audience participation part, I promise.
Part 1
Crash Course In RabbitMQ
1. What is RabbitMQ
2. Technology Overview
3. Publishers
4. Consumers
5. Exchanges
6. Queues
7. Bindings
– RabbitMQ In Action*, Manning
“RabbitMQ is an open source message broker
and queueing server that can be used to let
disparate applications share data via a common
protocol, or to simply queue jobs for processing
by distributed workers.

”
Where RabbitMQ Sits
(P) Producer/Publisher - (X) Exchange - (C) Consumer
Event Occurs in Application
(P) Producer/Publisher - (X) Exchange - (C) Consumer
Message is Sent to Exchange
(P) Producer/Publisher - (X) Exchange - (C) Consumer
Message is Sent to Queue
(P) Producer/Publisher - (X) Exchange - (C) Consumer
Exchanges connect to Queues through Bindings
Message is Sent to Consumer
(P) Producer/Publisher - (X) Exchange - (C) Consumer
– Me, Now
“Where as a database handles your data,
a message queue handles your events.”
A database handles nouns.
A message queue handles verbs.
But enough talk
Let’s see some code!
composer.json
"require": {

"videlalvaro/php-amqplib": "2.2.*"

}
We are starting with the publisher
Publisher: send.php
<?php

// Setup, $ php send.php whatever you want to send

require_once 'vendor/autoload.php';

$config = require('config.php');

use PhpAmqpLibConnectionAMQPConnection;

use PhpAmqpLibMessageAMQPMessage;



// Message Prep

$connection = new AMQPConnection($config['mq']['host'],

$config['mq']['port'],

$config['mq']['user'],

$config['mq']['pass']);



$channel = $connection->channel();

$message = join(' ', array_splice($argv, 1));

$message = empty($message) ? 'Hello world!' : $message;



// Publish Message

$channel->basic_publish(new AMQPMessage( $message ), '', 'hello');

echo " [x] Sent '$message'n";

$channel->close();

$connection->close();

Publisher: send.php
<?php

// Setup, $ php send.php whatever you want to send

require_once 'vendor/autoload.php';

$config = require('config.php');

use PhpAmqpLibConnectionAMQPConnection;

use PhpAmqpLibMessageAMQPMessage;



// Message Prep

$connection = new AMQPConnection($config['mq']['host'],

$config['mq']['port'],

$config['mq']['user'],

$config['mq']['pass']);



$channel = $connection->channel();

$message = join(' ', array_splice($argv, 1));

$message = empty($message) ? 'Hello world!' : $message;



// Publish Message

$channel->basic_publish(new AMQPMessage( $message ), '', 'hello');

echo " [x] Sent '$message'n";

$channel->close();

$connection->close();

Publisher: send.php
<?php

// Setup, $ php send.php whatever you want to send

require_once 'vendor/autoload.php';

$config = require('config.php');

use PhpAmqpLibConnectionAMQPConnection;

use PhpAmqpLibMessageAMQPMessage;



// Message Prep

$connection = new AMQPConnection($config['mq']['host'],

$config['mq']['port'],

$config['mq']['user'],

$config['mq']['pass']);



$channel = $connection->channel();

$message = join(' ', array_splice($argv, 1));

$message = empty($message) ? 'Hello world!' : $message;



// Publish Message

$channel->basic_publish(new AMQPMessage( $message ), '', 'hello');

echo " [x] Sent '$message'n";

$channel->close();

$connection->close();

Publisher: send.php
<?php

// Setup, $ php send.php whatever you want to send

require_once 'vendor/autoload.php';

$config = require('config.php');

use PhpAmqpLibConnectionAMQPConnection;

use PhpAmqpLibMessageAMQPMessage;



// Message Prep

$connection = new AMQPConnection($config['mq']['host'],

$config['mq']['port'],

$config['mq']['user'],

$config['mq']['pass']);



$channel = $connection->channel();

$message = join(' ', array_splice($argv, 1));

$message = empty($message) ? 'Hello world!' : $message;



// Publish Message

$channel->basic_publish(new AMQPMessage( $message ), '', 'hello');

echo " [x] Sent '$message'n";

$channel->close();

$connection->close();

Publisher: send.php
<?php

// Setup, $ php send.php whatever you want to send

require_once 'vendor/autoload.php';

$config = require('config.php');

use PhpAmqpLibConnectionAMQPConnection;

use PhpAmqpLibMessageAMQPMessage;



// Message Prep

$connection = new AMQPConnection($config['mq']['host'],

$config['mq']['port'],

$config['mq']['user'],

$config['mq']['pass']);



$channel = $connection->channel();

$message = join(' ', array_splice($argv, 1));

$message = empty($message) ? 'Hello world!' : $message;



// Publish Message

$channel->basic_publish(new AMQPMessage( $message ), '', 'hello');

echo " [x] Sent '$message'n";

$channel->close();

$connection->close();

Now we create a consumer
Consumer: receive.php
<?php



require_once 'vendor/autoload.php';

$config = require('config.php');

use PhpAmqpLibConnectionAMQPConnection;



$connection = new AMQPConnection($config['mq']['host'],

$config['mq']['port'],

$config['mq']['user'],

$config['mq']['pass']);

$channel = $connection->channel();

$channel->queue_declare('hello', false, false, false, true);



echo ' [*] Waiting for messages. To exit press CTRL+C', "n";



$handler = function($message) use($channel){

echo sprintf('Message: %s' . PHP_EOL, $message->body);

};



$channel->basic_consume('hello', false, true, true, false, false,
$handler);

$channel->wait();
Consumer: receive.php
<?php



require_once 'vendor/autoload.php';

$config = require('config.php');

use PhpAmqpLibConnectionAMQPConnection;



$connection = new AMQPConnection($config['mq']['host'],

$config['mq']['port'],

$config['mq']['user'],

$config['mq']['pass']);

$channel = $connection->channel();

$channel->queue_declare('hello', false, false, false, true);



echo ' [*] Waiting for messages. To exit press CTRL+C', "n";



$handler = function($message) use($channel){

echo sprintf('Message: %s' . PHP_EOL, $message->body);

};



$channel->basic_consume('hello', false, true, true, false, false,
$handler);

$channel->wait();
Consumer: receive.php
<?php



require_once 'vendor/autoload.php';

$config = require('config.php');

use PhpAmqpLibConnectionAMQPConnection;



$connection = new AMQPConnection($config['mq']['host'],

$config['mq']['port'],

$config['mq']['user'],

$config['mq']['pass']);

$channel = $connection->channel();

$channel->queue_declare('hello', false, false, false, true);



echo ' [*] Waiting for messages. To exit press CTRL+C', "n";



$handler = function($message) use($channel){

echo sprintf('Message: %s' . PHP_EOL, $message->body);

};



$channel->basic_consume('hello', false, true, true, false, false,
$handler);

$channel->wait();
Consumer: receive.php
<?php



require_once 'vendor/autoload.php';

$config = require('config.php');

use PhpAmqpLibConnectionAMQPConnection;



$connection = new AMQPConnection($config['mq']['host'],

$config['mq']['port'],

$config['mq']['user'],

$config['mq']['pass']);

$channel = $connection->channel();

$channel->queue_declare('hello', false, false, false, true);



echo ' [*] Waiting for messages. To exit press CTRL+C', "n";



$handler = function($message) use($channel){

echo sprintf('Message: %s' . PHP_EOL, $message->body);

};



$channel->basic_consume('hello', false, true, true, false, false,
$handler);

$channel->wait();
Message is Sent to Exchange
(P) Producer/Publisher - (X) Exchange - (C) Consumer
Exchange Types
Direct, Fanout, and Topic
Queue bound to many exchanges
$msg = new AMQPMessage( $message );

$channel->basic_publish($msg, '', ‘messages.new');
* matches one word
# matches zero or more words
A word is delineated by .
*, #, and .
*.new
messages.*
NOT *.messages.*
messages.new matches
NOT spam.*
spam.*.*
spam.#
spam.message.new matches
Now Let’s Create an
Exchange and a Queue
Using the Management UI
rabbitmq-plugins enable rabbitmq_management
http://localhost:15672
We’ve Created Everything
Publishers, Exchanges, Bindings, Queues, and Consumers
So what can we do with this?
Part 2
PHP & RabbitMQ Together
1. Carrot to make things easy
2. Publish events from the web
3. Multiple consumers
4. Management UI Publishing
5. Consumers Publishing
Carrot
github.com/jasonlotito/Carrot
Carrot Consumer Code
<?php

require_once 'vendor/autoload.php';



use CarrotConsumer;
$queue = 'new_messages';

$handler = function($msg){

echo $msg, PHP_EOL;

return true;

};


(new Consumer())->listenTo($queue, $handler)

->listenAndWait();!
Carrot Publisher Code
<?php

require 'vendor/autoload.php';



use CarrotPublisher;



$msg = implode(' ', array_splice($argv, 1));

(new Publisher('messages'))

->publish('message.new', $msg);
Make publishing easy
Make consuming easier
github.com/jasonlotito/
midwest-rabbitmq/tree/carrot
Adding the Web
Publisher
$publisher = new Publisher('messages');

$sendCount = (int) (isset($_POST['simulatedMessageCount']) ?
$_POST['simulatedMessageCount'] : 1);



for($x = 0; $x<$sendCount; $x++){

if(isset($_POST['simulateWork'])) {

usleep(500000);

$msg = ['comment' => $_POST['comment'] . " $x"];

$publisher->eventuallyPublish('message.new', $msg);

} else {

$msg = ['comment' => $_POST['comment'] . " $x"];

$publisher->publish('message.new', $msg);

}

}
Let’s use the written
Carrot Consumer Code
batch_basic_publish
public function eventuallyPublish($routingKey, $message)

{

$msg = $this->buildMessage($message);

$channel = $this->getChannel();

$channel->batch_basic_publish($msg, $this->exchange,
$routingKey);

$this->registerShutdownHandler();

}



public function finallyPublish()

{

if ($this->doBatchPublish) {

$this->doBatchPublish = false;

$this->getChannel()->publish_batch();

}

}
!
// register finallyPublish
private function registerShutdownHandler();

Publish from the web
Let’s add another consumer
Without changing existing code
send text messages
$queueName = 'messages_for_nexmo';



(new Consumer())

->bind($queueName, 'messages', 'message.new')

->listenTo($queueName, function($msg) use($key, $secret, $phoneNumber) {

$msg = json_decode($msg);

$urlString = 'https://rest.nexmo.com/sms/json?api_key=%s&api_secret=%s' .

'&from=17088568489&to=%s&text=%s';

$preparedMessage = urlencode($msg->comment);

$url = sprintf($urlString, $key, $secret, $phoneNumber, $preparedMessage);

$res = file_get_contents($url);

$result = json_decode($res);

$messageResult = $result->messages[0];

echo "Message Result: " .

($messageResult->status === '0' ? 'Message Sent' : 'Message not sent')

. PHP_EOL;

return $messageResult->status === '0';

})->listenAndWait();

send text messages
$queueName = 'messages_for_nexmo';



(new Consumer())

->bind($queueName, 'messages', 'message.new')

->listenTo($queueName, function($msg) use($key, $secret, $phoneNumber) {

$msg = json_decode($msg);

$urlString = 'https://rest.nexmo.com/sms/json?api_key=%s&api_secret=%s' .

'&from=17088568489&to=%s&text=%s';

$preparedMessage = urlencode($msg->comment);

$url = sprintf($urlString, $key, $secret, $phoneNumber, $preparedMessage);

$res = file_get_contents($url);

$result = json_decode($res);

$messageResult = $result->messages[0];

echo "Message Result: " .

($messageResult->status === '0' ? 'Message Sent' : 'Message not sent')

. PHP_EOL;

return $messageResult->status === '0';

})->listenAndWait();

send text messages
$queueName = 'messages_for_nexmo';



(new Consumer())

->bind($queueName, 'messages', 'message.new')

->listenTo($queueName, function($msg) use($key, $secret, $phoneNumber) {

$msg = json_decode($msg);

$urlString = 'https://rest.nexmo.com/sms/json?api_key=%s&api_secret=%s' .

'&from=17088568489&to=%s&text=%s';

$preparedMessage = urlencode($msg->comment);

$url = sprintf($urlString, $key, $secret, $phoneNumber, $preparedMessage);

$res = file_get_contents($url);

$result = json_decode($res);

$messageResult = $result->messages[0];

echo "Message Result: " .

($messageResult->status === '0' ? 'Message Sent' : 'Message not sent')

. PHP_EOL;

return $messageResult->status === '0';

})->listenAndWait();

Both queues get the message
Let’s add another layer
Yo dawg, let’s have a
consumer publish
Send an email
After the text message
Create a new Exchange
Update text message consumer
$publisher = new Publisher('sms');



(new Consumer())

->bind($queueName, 'messages', 'message.new')

->listenTo($queueName, function($msg) use($key, $secret, $phoneNumber, $publisher) {

// existing code

$successful = $messageResult->status === '0';



if ($successful) {

$publisher->publish(‘sms.sent', ['message' => $msg->comment]);

}



return $successful;

})->listenAndWait();

Let’s write the email consumer
And I’ll also show you how to easily test them
Email Consumer
(new Consumer())

->bind('send_email', 'emails', '*.send')

->bind('send_email', 'sms', '*.sent')

->listenTo('send_email', function($message){

$msg = json_decode($message);

mail('jasonlotito@gmail.com', 'MidwestPHP RabbitMQ Talk',
$msg->message);

echo 'Message sent: ' . $msg->message . PHP_EOL;

return true;

})->listenAndWait();
Email consumer
(new Consumer())

->bind('send_email', 'emails', '*.send')

->bind('send_email', 'sms', '*.sent')

->listenTo('send_email', function($message){

$msg = json_decode($message);

mail('jasonlotito@gmail.com', 'MidwestPHP RabbitMQ Talk',
$msg->message);

echo 'Message sent: ' . $msg->message . PHP_EOL;

return true;

})->listenAndWait();
Now, let’s see it
from the beginning
rabbitmq.org
Thank you. Review: joind.in/10558
#midwestphp #rabbitmq
Questions? Feel free to stop and ask me, email, tweet, @jasonlotito@gmail.com

Más contenido relacionado

La actualidad más candente

Working with web_services
Working with web_servicesWorking with web_services
Working with web_servicesLorna Mitchell
 
Operation Oriented Web Applications / Yokohama pm7
Operation Oriented Web Applications / Yokohama pm7Operation Oriented Web Applications / Yokohama pm7
Operation Oriented Web Applications / Yokohama pm7Masahiro Nagano
 
Perl web frameworks
Perl web frameworksPerl web frameworks
Perl web frameworksdiego_k
 
AnyMQ, Hippie, and the real-time web
AnyMQ, Hippie, and the real-time webAnyMQ, Hippie, and the real-time web
AnyMQ, Hippie, and the real-time webclkao
 
Redis for your boss 2.0
Redis for your boss 2.0Redis for your boss 2.0
Redis for your boss 2.0Elena Kolevska
 
Asynchronous programming patterns in Perl
Asynchronous programming patterns in PerlAsynchronous programming patterns in Perl
Asynchronous programming patterns in Perldeepfountainconsulting
 
Webrtc mojo
Webrtc mojoWebrtc mojo
Webrtc mojobpmedley
 
Cli the other SAPI confoo11
Cli the other SAPI confoo11Cli the other SAPI confoo11
Cli the other SAPI confoo11Combell NV
 
Zephir - A Wind of Change for writing PHP extensions
Zephir - A Wind of Change for writing PHP extensionsZephir - A Wind of Change for writing PHP extensions
Zephir - A Wind of Change for writing PHP extensionsMark Baker
 
Php on the Web and Desktop
Php on the Web and DesktopPhp on the Web and Desktop
Php on the Web and DesktopElizabeth Smith
 
CLI, the other SAPI phpnw11
CLI, the other SAPI phpnw11CLI, the other SAPI phpnw11
CLI, the other SAPI phpnw11Combell NV
 
Inside Bokete: Web Application with Mojolicious and others
Inside Bokete:  Web Application with Mojolicious and othersInside Bokete:  Web Application with Mojolicious and others
Inside Bokete: Web Application with Mojolicious and othersYusuke Wada
 
PECL Picks - Extensions to make your life better
PECL Picks - Extensions to make your life betterPECL Picks - Extensions to make your life better
PECL Picks - Extensions to make your life betterZendCon
 

La actualidad más candente (20)

Working with web_services
Working with web_servicesWorking with web_services
Working with web_services
 
Operation Oriented Web Applications / Yokohama pm7
Operation Oriented Web Applications / Yokohama pm7Operation Oriented Web Applications / Yokohama pm7
Operation Oriented Web Applications / Yokohama pm7
 
Perl web frameworks
Perl web frameworksPerl web frameworks
Perl web frameworks
 
Redis for your boss
Redis for your bossRedis for your boss
Redis for your boss
 
AnyMQ, Hippie, and the real-time web
AnyMQ, Hippie, and the real-time webAnyMQ, Hippie, and the real-time web
AnyMQ, Hippie, and the real-time web
 
Redis for your boss 2.0
Redis for your boss 2.0Redis for your boss 2.0
Redis for your boss 2.0
 
Asynchronous programming patterns in Perl
Asynchronous programming patterns in PerlAsynchronous programming patterns in Perl
Asynchronous programming patterns in Perl
 
Mojo as a_client
Mojo as a_clientMojo as a_client
Mojo as a_client
 
Webrtc mojo
Webrtc mojoWebrtc mojo
Webrtc mojo
 
Cli the other SAPI confoo11
Cli the other SAPI confoo11Cli the other SAPI confoo11
Cli the other SAPI confoo11
 
Zephir - A Wind of Change for writing PHP extensions
Zephir - A Wind of Change for writing PHP extensionsZephir - A Wind of Change for writing PHP extensions
Zephir - A Wind of Change for writing PHP extensions
 
ReactPHP
ReactPHPReactPHP
ReactPHP
 
Php on the Web and Desktop
Php on the Web and DesktopPhp on the Web and Desktop
Php on the Web and Desktop
 
CLI, the other SAPI phpnw11
CLI, the other SAPI phpnw11CLI, the other SAPI phpnw11
CLI, the other SAPI phpnw11
 
Developing apps using Perl
Developing apps using PerlDeveloping apps using Perl
Developing apps using Perl
 
Let's Talk Scope
Let's Talk ScopeLet's Talk Scope
Let's Talk Scope
 
Inside Bokete: Web Application with Mojolicious and others
Inside Bokete:  Web Application with Mojolicious and othersInside Bokete:  Web Application with Mojolicious and others
Inside Bokete: Web Application with Mojolicious and others
 
PHP
PHPPHP
PHP
 
RESTful web services
RESTful web servicesRESTful web services
RESTful web services
 
PECL Picks - Extensions to make your life better
PECL Picks - Extensions to make your life betterPECL Picks - Extensions to make your life better
PECL Picks - Extensions to make your life better
 

Destacado

Integrating RabbitMQ with PHP
Integrating RabbitMQ with PHPIntegrating RabbitMQ with PHP
Integrating RabbitMQ with PHPAlvaro Videla
 
ByndyuSoft 1 год глазами программиста
ByndyuSoft 1 год глазами программистаByndyuSoft 1 год глазами программиста
ByndyuSoft 1 год глазами программистаRuslan Safin
 
Компания мечты своими руками, Уфа,
Компания мечты своими руками, Уфа, Компания мечты своими руками, Уфа,
Компания мечты своими руками, Уфа, Alexander Byndyu
 
Карьера в IT, 27-02-2013
Карьера в IT, 27-02-2013Карьера в IT, 27-02-2013
Карьера в IT, 27-02-2013Alexander Byndyu
 
Антон Довгоброд: Highload и очереди задач на примере PHP + Gearman + Yii2
Антон Довгоброд: Highload и очереди задач на примере PHP + Gearman + Yii2Антон Довгоброд: Highload и очереди задач на примере PHP + Gearman + Yii2
Антон Довгоброд: Highload и очереди задач на примере PHP + Gearman + Yii2Oleg Poludnenko
 
What RabbitMQ Can Do For You (Nomad PHP May 2014)
What RabbitMQ Can Do For You (Nomad PHP May 2014)What RabbitMQ Can Do For You (Nomad PHP May 2014)
What RabbitMQ Can Do For You (Nomad PHP May 2014)James Titcumb
 
Theres a rabbit on my symfony
Theres a rabbit on my symfonyTheres a rabbit on my symfony
Theres a rabbit on my symfonyAlvaro Videla
 
Introduction to AMQP Messaging with RabbitMQ
Introduction to AMQP Messaging with RabbitMQIntroduction to AMQP Messaging with RabbitMQ
Introduction to AMQP Messaging with RabbitMQDmitriy Samovskiy
 

Destacado (8)

Integrating RabbitMQ with PHP
Integrating RabbitMQ with PHPIntegrating RabbitMQ with PHP
Integrating RabbitMQ with PHP
 
ByndyuSoft 1 год глазами программиста
ByndyuSoft 1 год глазами программистаByndyuSoft 1 год глазами программиста
ByndyuSoft 1 год глазами программиста
 
Компания мечты своими руками, Уфа,
Компания мечты своими руками, Уфа, Компания мечты своими руками, Уфа,
Компания мечты своими руками, Уфа,
 
Карьера в IT, 27-02-2013
Карьера в IT, 27-02-2013Карьера в IT, 27-02-2013
Карьера в IT, 27-02-2013
 
Антон Довгоброд: Highload и очереди задач на примере PHP + Gearman + Yii2
Антон Довгоброд: Highload и очереди задач на примере PHP + Gearman + Yii2Антон Довгоброд: Highload и очереди задач на примере PHP + Gearman + Yii2
Антон Довгоброд: Highload и очереди задач на примере PHP + Gearman + Yii2
 
What RabbitMQ Can Do For You (Nomad PHP May 2014)
What RabbitMQ Can Do For You (Nomad PHP May 2014)What RabbitMQ Can Do For You (Nomad PHP May 2014)
What RabbitMQ Can Do For You (Nomad PHP May 2014)
 
Theres a rabbit on my symfony
Theres a rabbit on my symfonyTheres a rabbit on my symfony
Theres a rabbit on my symfony
 
Introduction to AMQP Messaging with RabbitMQ
Introduction to AMQP Messaging with RabbitMQIntroduction to AMQP Messaging with RabbitMQ
Introduction to AMQP Messaging with RabbitMQ
 

Similar a PHP, RabbitMQ, and You

Adding 1.21 Gigawatts to Applications with RabbitMQ (PHPNW Dec 2014 Meetup)
Adding 1.21 Gigawatts to Applications with RabbitMQ (PHPNW Dec 2014 Meetup)Adding 1.21 Gigawatts to Applications with RabbitMQ (PHPNW Dec 2014 Meetup)
Adding 1.21 Gigawatts to Applications with RabbitMQ (PHPNW Dec 2014 Meetup)James Titcumb
 
How to build a High Performance PSGI/Plack Server
How to build a High Performance PSGI/Plack Server How to build a High Performance PSGI/Plack Server
How to build a High Performance PSGI/Plack Server Masahiro Nagano
 
Facebook的缓存系统
Facebook的缓存系统Facebook的缓存系统
Facebook的缓存系统yiditushe
 
13 PHPUnit #burningkeyboards
13 PHPUnit #burningkeyboards13 PHPUnit #burningkeyboards
13 PHPUnit #burningkeyboardsDenis Ristic
 
Adding 1.21 Gigawatts to Applications with RabbitMQ (DPC 2015)
Adding 1.21 Gigawatts to Applications with RabbitMQ (DPC 2015)Adding 1.21 Gigawatts to Applications with RabbitMQ (DPC 2015)
Adding 1.21 Gigawatts to Applications with RabbitMQ (DPC 2015)James Titcumb
 
4069180 Caching Performance Lessons From Facebook
4069180 Caching Performance Lessons From Facebook4069180 Caching Performance Lessons From Facebook
4069180 Caching Performance Lessons From Facebookguoqing75
 
PSGI and Plack from first principles
PSGI and Plack from first principlesPSGI and Plack from first principles
PSGI and Plack from first principlesPerl Careers
 
PHP And Web Services: Perfect Partners
PHP And Web Services: Perfect PartnersPHP And Web Services: Perfect Partners
PHP And Web Services: Perfect PartnersLorna Mitchell
 
関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐいHisateru Tanaka
 
Mojolicious. Веб в коробке!
Mojolicious. Веб в коробке!Mojolicious. Веб в коробке!
Mojolicious. Веб в коробке!Anatoly Sharifulin
 
Giới thiệu PHP 7
Giới thiệu PHP 7Giới thiệu PHP 7
Giới thiệu PHP 7ZendVN
 
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQueryRemedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQueryTatsuhiko Miyagawa
 
Simple callcenter platform with PHP
Simple callcenter platform with PHPSimple callcenter platform with PHP
Simple callcenter platform with PHPMorten Amundsen
 
Ch ch-changes cake php2
Ch ch-changes cake php2Ch ch-changes cake php2
Ch ch-changes cake php2markstory
 
Building and Incredible Machine with Pipelines and Generators in PHP (IPC Ber...
Building and Incredible Machine with Pipelines and Generators in PHP (IPC Ber...Building and Incredible Machine with Pipelines and Generators in PHP (IPC Ber...
Building and Incredible Machine with Pipelines and Generators in PHP (IPC Ber...dantleech
 
The symfony platform: Create your very own framework (PHP Quebec 2008)
The symfony platform: Create your very own framework (PHP Quebec 2008)The symfony platform: Create your very own framework (PHP Quebec 2008)
The symfony platform: Create your very own framework (PHP Quebec 2008)Fabien Potencier
 

Similar a PHP, RabbitMQ, and You (20)

Adding 1.21 Gigawatts to Applications with RabbitMQ (PHPNW Dec 2014 Meetup)
Adding 1.21 Gigawatts to Applications with RabbitMQ (PHPNW Dec 2014 Meetup)Adding 1.21 Gigawatts to Applications with RabbitMQ (PHPNW Dec 2014 Meetup)
Adding 1.21 Gigawatts to Applications with RabbitMQ (PHPNW Dec 2014 Meetup)
 
Tatsumaki
TatsumakiTatsumaki
Tatsumaki
 
How to build a High Performance PSGI/Plack Server
How to build a High Performance PSGI/Plack Server How to build a High Performance PSGI/Plack Server
How to build a High Performance PSGI/Plack Server
 
Facebook的缓存系统
Facebook的缓存系统Facebook的缓存系统
Facebook的缓存系统
 
13 PHPUnit #burningkeyboards
13 PHPUnit #burningkeyboards13 PHPUnit #burningkeyboards
13 PHPUnit #burningkeyboards
 
Adding 1.21 Gigawatts to Applications with RabbitMQ (DPC 2015)
Adding 1.21 Gigawatts to Applications with RabbitMQ (DPC 2015)Adding 1.21 Gigawatts to Applications with RabbitMQ (DPC 2015)
Adding 1.21 Gigawatts to Applications with RabbitMQ (DPC 2015)
 
4069180 Caching Performance Lessons From Facebook
4069180 Caching Performance Lessons From Facebook4069180 Caching Performance Lessons From Facebook
4069180 Caching Performance Lessons From Facebook
 
PSGI and Plack from first principles
PSGI and Plack from first principlesPSGI and Plack from first principles
PSGI and Plack from first principles
 
PHP And Web Services: Perfect Partners
PHP And Web Services: Perfect PartnersPHP And Web Services: Perfect Partners
PHP And Web Services: Perfect Partners
 
関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい
 
Mojolicious. Веб в коробке!
Mojolicious. Веб в коробке!Mojolicious. Веб в коробке!
Mojolicious. Веб в коробке!
 
Php hacku
Php hackuPhp hacku
Php hacku
 
Giới thiệu PHP 7
Giới thiệu PHP 7Giới thiệu PHP 7
Giới thiệu PHP 7
 
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQueryRemedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
Remedie: Building a desktop app with HTTP::Engine, SQLite and jQuery
 
Simple callcenter platform with PHP
Simple callcenter platform with PHPSimple callcenter platform with PHP
Simple callcenter platform with PHP
 
Ch ch-changes cake php2
Ch ch-changes cake php2Ch ch-changes cake php2
Ch ch-changes cake php2
 
PhpBB meets Symfony2
PhpBB meets Symfony2PhpBB meets Symfony2
PhpBB meets Symfony2
 
Mojolicious
MojoliciousMojolicious
Mojolicious
 
Building and Incredible Machine with Pipelines and Generators in PHP (IPC Ber...
Building and Incredible Machine with Pipelines and Generators in PHP (IPC Ber...Building and Incredible Machine with Pipelines and Generators in PHP (IPC Ber...
Building and Incredible Machine with Pipelines and Generators in PHP (IPC Ber...
 
The symfony platform: Create your very own framework (PHP Quebec 2008)
The symfony platform: Create your very own framework (PHP Quebec 2008)The symfony platform: Create your very own framework (PHP Quebec 2008)
The symfony platform: Create your very own framework (PHP Quebec 2008)
 

Más de Jason Lotito

A Presentation on Presenting
A Presentation on PresentingA Presentation on Presenting
A Presentation on PresentingJason Lotito
 
Load Testing with PHP and RedLine13
Load Testing with PHP and RedLine13Load Testing with PHP and RedLine13
Load Testing with PHP and RedLine13Jason Lotito
 
Load Testing with RedLine13: Or getting paid to DoS your own systems
Load Testing with RedLine13: Or getting paid to DoS your own systemsLoad Testing with RedLine13: Or getting paid to DoS your own systems
Load Testing with RedLine13: Or getting paid to DoS your own systemsJason Lotito
 
Getting Things Done - Tips from someone with ADHD and OCD
Getting Things Done - Tips from someone with ADHD and OCDGetting Things Done - Tips from someone with ADHD and OCD
Getting Things Done - Tips from someone with ADHD and OCDJason Lotito
 
How we killed our process, technology stack, and assumptions – and survived
How we killed our process, technology stack, and assumptions – and survivedHow we killed our process, technology stack, and assumptions – and survived
How we killed our process, technology stack, and assumptions – and survivedJason Lotito
 
Twitter Bootstrap, or why being a PHP Developer is a bad idea
Twitter Bootstrap, or why being a PHP Developer is a bad ideaTwitter Bootstrap, or why being a PHP Developer is a bad idea
Twitter Bootstrap, or why being a PHP Developer is a bad ideaJason Lotito
 

Más de Jason Lotito (9)

A Presentation on Presenting
A Presentation on PresentingA Presentation on Presenting
A Presentation on Presenting
 
Load Testing with PHP and RedLine13
Load Testing with PHP and RedLine13Load Testing with PHP and RedLine13
Load Testing with PHP and RedLine13
 
Load Testing with RedLine13: Or getting paid to DoS your own systems
Load Testing with RedLine13: Or getting paid to DoS your own systemsLoad Testing with RedLine13: Or getting paid to DoS your own systems
Load Testing with RedLine13: Or getting paid to DoS your own systems
 
tmux
tmuxtmux
tmux
 
Getting Things Done - Tips from someone with ADHD and OCD
Getting Things Done - Tips from someone with ADHD and OCDGetting Things Done - Tips from someone with ADHD and OCD
Getting Things Done - Tips from someone with ADHD and OCD
 
How we killed our process, technology stack, and assumptions – and survived
How we killed our process, technology stack, and assumptions – and survivedHow we killed our process, technology stack, and assumptions – and survived
How we killed our process, technology stack, and assumptions – and survived
 
Twitter Bootstrap, or why being a PHP Developer is a bad idea
Twitter Bootstrap, or why being a PHP Developer is a bad ideaTwitter Bootstrap, or why being a PHP Developer is a bad idea
Twitter Bootstrap, or why being a PHP Developer is a bad idea
 
Requirejs
RequirejsRequirejs
Requirejs
 
Tmux
TmuxTmux
Tmux
 

Último

Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Enterprise Knowledge
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Commit University
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxhariprasad279825
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piececharlottematthew16
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsMiki Katsuragi
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clashcharlottematthew16
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Mattias Andersson
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostZilliz
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Manik S Magar
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):comworks
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 

Último (20)

Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptx
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piece
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering Tips
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clash
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
DMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special EditionDMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special Edition
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 

PHP, RabbitMQ, and You

  • 1. PHP, RabbitMQ, and You #mwphp14 #rabbitmq @jasonlotito MidwestPHP 2014 - RabbitMQ What will we be covering? 1. What is RabbitMQ 2. Technology Overview 3. Publishers 4. Consumers 5. Exchanges 6. Queues 7. Bindings 8. Carrot to make things easy 9. Publish events from the web 10.Multiple consumers 11.Management UI Publishing 12.Consumers Publishing
  • 2. PHP, RabbitMQ, and You #mwphp14 #rabbitmq @jasonlotito
  • 3. Jason Lotito Senior Architect @ MeetMe @jasonlotito.com github.com/jasonlotito@gmail.com ! Senior Architect means people can blame me when things don’t work as expected. When things work, it’s because they worked around my code.
  • 4. Who has worked with RabbitMQ in production? Raise your hands. The only audience participation part, I promise.
  • 5. Part 1 Crash Course In RabbitMQ 1. What is RabbitMQ 2. Technology Overview 3. Publishers 4. Consumers 5. Exchanges 6. Queues 7. Bindings
  • 6. – RabbitMQ In Action*, Manning “RabbitMQ is an open source message broker and queueing server that can be used to let disparate applications share data via a common protocol, or to simply queue jobs for processing by distributed workers. ”
  • 7. Where RabbitMQ Sits (P) Producer/Publisher - (X) Exchange - (C) Consumer
  • 8. Event Occurs in Application (P) Producer/Publisher - (X) Exchange - (C) Consumer
  • 9. Message is Sent to Exchange (P) Producer/Publisher - (X) Exchange - (C) Consumer
  • 10. Message is Sent to Queue (P) Producer/Publisher - (X) Exchange - (C) Consumer Exchanges connect to Queues through Bindings
  • 11. Message is Sent to Consumer (P) Producer/Publisher - (X) Exchange - (C) Consumer
  • 12. – Me, Now “Where as a database handles your data, a message queue handles your events.”
  • 13. A database handles nouns. A message queue handles verbs.
  • 14. But enough talk Let’s see some code!
  • 16. We are starting with the publisher
  • 17. Publisher: send.php <?php
 // Setup, $ php send.php whatever you want to send
 require_once 'vendor/autoload.php';
 $config = require('config.php');
 use PhpAmqpLibConnectionAMQPConnection;
 use PhpAmqpLibMessageAMQPMessage;
 
 // Message Prep
 $connection = new AMQPConnection($config['mq']['host'],
 $config['mq']['port'],
 $config['mq']['user'],
 $config['mq']['pass']);
 
 $channel = $connection->channel();
 $message = join(' ', array_splice($argv, 1));
 $message = empty($message) ? 'Hello world!' : $message;
 
 // Publish Message
 $channel->basic_publish(new AMQPMessage( $message ), '', 'hello');
 echo " [x] Sent '$message'n";
 $channel->close();
 $connection->close();

  • 18. Publisher: send.php <?php
 // Setup, $ php send.php whatever you want to send
 require_once 'vendor/autoload.php';
 $config = require('config.php');
 use PhpAmqpLibConnectionAMQPConnection;
 use PhpAmqpLibMessageAMQPMessage;
 
 // Message Prep
 $connection = new AMQPConnection($config['mq']['host'],
 $config['mq']['port'],
 $config['mq']['user'],
 $config['mq']['pass']);
 
 $channel = $connection->channel();
 $message = join(' ', array_splice($argv, 1));
 $message = empty($message) ? 'Hello world!' : $message;
 
 // Publish Message
 $channel->basic_publish(new AMQPMessage( $message ), '', 'hello');
 echo " [x] Sent '$message'n";
 $channel->close();
 $connection->close();

  • 19. Publisher: send.php <?php
 // Setup, $ php send.php whatever you want to send
 require_once 'vendor/autoload.php';
 $config = require('config.php');
 use PhpAmqpLibConnectionAMQPConnection;
 use PhpAmqpLibMessageAMQPMessage;
 
 // Message Prep
 $connection = new AMQPConnection($config['mq']['host'],
 $config['mq']['port'],
 $config['mq']['user'],
 $config['mq']['pass']);
 
 $channel = $connection->channel();
 $message = join(' ', array_splice($argv, 1));
 $message = empty($message) ? 'Hello world!' : $message;
 
 // Publish Message
 $channel->basic_publish(new AMQPMessage( $message ), '', 'hello');
 echo " [x] Sent '$message'n";
 $channel->close();
 $connection->close();

  • 20. Publisher: send.php <?php
 // Setup, $ php send.php whatever you want to send
 require_once 'vendor/autoload.php';
 $config = require('config.php');
 use PhpAmqpLibConnectionAMQPConnection;
 use PhpAmqpLibMessageAMQPMessage;
 
 // Message Prep
 $connection = new AMQPConnection($config['mq']['host'],
 $config['mq']['port'],
 $config['mq']['user'],
 $config['mq']['pass']);
 
 $channel = $connection->channel();
 $message = join(' ', array_splice($argv, 1));
 $message = empty($message) ? 'Hello world!' : $message;
 
 // Publish Message
 $channel->basic_publish(new AMQPMessage( $message ), '', 'hello');
 echo " [x] Sent '$message'n";
 $channel->close();
 $connection->close();

  • 21. Publisher: send.php <?php
 // Setup, $ php send.php whatever you want to send
 require_once 'vendor/autoload.php';
 $config = require('config.php');
 use PhpAmqpLibConnectionAMQPConnection;
 use PhpAmqpLibMessageAMQPMessage;
 
 // Message Prep
 $connection = new AMQPConnection($config['mq']['host'],
 $config['mq']['port'],
 $config['mq']['user'],
 $config['mq']['pass']);
 
 $channel = $connection->channel();
 $message = join(' ', array_splice($argv, 1));
 $message = empty($message) ? 'Hello world!' : $message;
 
 // Publish Message
 $channel->basic_publish(new AMQPMessage( $message ), '', 'hello');
 echo " [x] Sent '$message'n";
 $channel->close();
 $connection->close();

  • 22. Now we create a consumer
  • 23. Consumer: receive.php <?php
 
 require_once 'vendor/autoload.php';
 $config = require('config.php');
 use PhpAmqpLibConnectionAMQPConnection;
 
 $connection = new AMQPConnection($config['mq']['host'],
 $config['mq']['port'],
 $config['mq']['user'],
 $config['mq']['pass']);
 $channel = $connection->channel();
 $channel->queue_declare('hello', false, false, false, true);
 
 echo ' [*] Waiting for messages. To exit press CTRL+C', "n";
 
 $handler = function($message) use($channel){
 echo sprintf('Message: %s' . PHP_EOL, $message->body);
 };
 
 $channel->basic_consume('hello', false, true, true, false, false, $handler);
 $channel->wait();
  • 24. Consumer: receive.php <?php
 
 require_once 'vendor/autoload.php';
 $config = require('config.php');
 use PhpAmqpLibConnectionAMQPConnection;
 
 $connection = new AMQPConnection($config['mq']['host'],
 $config['mq']['port'],
 $config['mq']['user'],
 $config['mq']['pass']);
 $channel = $connection->channel();
 $channel->queue_declare('hello', false, false, false, true);
 
 echo ' [*] Waiting for messages. To exit press CTRL+C', "n";
 
 $handler = function($message) use($channel){
 echo sprintf('Message: %s' . PHP_EOL, $message->body);
 };
 
 $channel->basic_consume('hello', false, true, true, false, false, $handler);
 $channel->wait();
  • 25. Consumer: receive.php <?php
 
 require_once 'vendor/autoload.php';
 $config = require('config.php');
 use PhpAmqpLibConnectionAMQPConnection;
 
 $connection = new AMQPConnection($config['mq']['host'],
 $config['mq']['port'],
 $config['mq']['user'],
 $config['mq']['pass']);
 $channel = $connection->channel();
 $channel->queue_declare('hello', false, false, false, true);
 
 echo ' [*] Waiting for messages. To exit press CTRL+C', "n";
 
 $handler = function($message) use($channel){
 echo sprintf('Message: %s' . PHP_EOL, $message->body);
 };
 
 $channel->basic_consume('hello', false, true, true, false, false, $handler);
 $channel->wait();
  • 26. Consumer: receive.php <?php
 
 require_once 'vendor/autoload.php';
 $config = require('config.php');
 use PhpAmqpLibConnectionAMQPConnection;
 
 $connection = new AMQPConnection($config['mq']['host'],
 $config['mq']['port'],
 $config['mq']['user'],
 $config['mq']['pass']);
 $channel = $connection->channel();
 $channel->queue_declare('hello', false, false, false, true);
 
 echo ' [*] Waiting for messages. To exit press CTRL+C', "n";
 
 $handler = function($message) use($channel){
 echo sprintf('Message: %s' . PHP_EOL, $message->body);
 };
 
 $channel->basic_consume('hello', false, true, true, false, false, $handler);
 $channel->wait();
  • 27.
  • 28. Message is Sent to Exchange (P) Producer/Publisher - (X) Exchange - (C) Consumer
  • 30.
  • 31.
  • 32.
  • 33. Queue bound to many exchanges
  • 34. $msg = new AMQPMessage( $message );
 $channel->basic_publish($msg, '', ‘messages.new');
  • 35. * matches one word # matches zero or more words A word is delineated by . *, #, and .
  • 38. Now Let’s Create an Exchange and a Queue
  • 39. Using the Management UI rabbitmq-plugins enable rabbitmq_management http://localhost:15672
  • 40.
  • 41.
  • 42. We’ve Created Everything Publishers, Exchanges, Bindings, Queues, and Consumers
  • 43. So what can we do with this?
  • 44. Part 2 PHP & RabbitMQ Together 1. Carrot to make things easy 2. Publish events from the web 3. Multiple consumers 4. Management UI Publishing 5. Consumers Publishing
  • 46. Carrot Consumer Code <?php
 require_once 'vendor/autoload.php';
 
 use CarrotConsumer; $queue = 'new_messages';
 $handler = function($msg){
 echo $msg, PHP_EOL;
 return true;
 }; 
 (new Consumer())->listenTo($queue, $handler)
 ->listenAndWait();!
  • 47. Carrot Publisher Code <?php
 require 'vendor/autoload.php';
 
 use CarrotPublisher;
 
 $msg = implode(' ', array_splice($argv, 1));
 (new Publisher('messages'))
 ->publish('message.new', $msg);
  • 48.
  • 53. Publisher $publisher = new Publisher('messages');
 $sendCount = (int) (isset($_POST['simulatedMessageCount']) ? $_POST['simulatedMessageCount'] : 1);
 
 for($x = 0; $x<$sendCount; $x++){
 if(isset($_POST['simulateWork'])) {
 usleep(500000);
 $msg = ['comment' => $_POST['comment'] . " $x"];
 $publisher->eventuallyPublish('message.new', $msg);
 } else {
 $msg = ['comment' => $_POST['comment'] . " $x"];
 $publisher->publish('message.new', $msg);
 }
 }
  • 54. Let’s use the written Carrot Consumer Code
  • 55.
  • 56. batch_basic_publish public function eventuallyPublish($routingKey, $message)
 {
 $msg = $this->buildMessage($message);
 $channel = $this->getChannel();
 $channel->batch_basic_publish($msg, $this->exchange, $routingKey);
 $this->registerShutdownHandler();
 }
 
 public function finallyPublish()
 {
 if ($this->doBatchPublish) {
 $this->doBatchPublish = false;
 $this->getChannel()->publish_batch();
 }
 } ! // register finallyPublish private function registerShutdownHandler();

  • 57. Publish from the web Let’s add another consumer Without changing existing code
  • 58. send text messages $queueName = 'messages_for_nexmo';
 
 (new Consumer())
 ->bind($queueName, 'messages', 'message.new')
 ->listenTo($queueName, function($msg) use($key, $secret, $phoneNumber) {
 $msg = json_decode($msg);
 $urlString = 'https://rest.nexmo.com/sms/json?api_key=%s&api_secret=%s' .
 '&from=17088568489&to=%s&text=%s';
 $preparedMessage = urlencode($msg->comment);
 $url = sprintf($urlString, $key, $secret, $phoneNumber, $preparedMessage);
 $res = file_get_contents($url);
 $result = json_decode($res);
 $messageResult = $result->messages[0];
 echo "Message Result: " .
 ($messageResult->status === '0' ? 'Message Sent' : 'Message not sent')
 . PHP_EOL;
 return $messageResult->status === '0';
 })->listenAndWait();

  • 59. send text messages $queueName = 'messages_for_nexmo';
 
 (new Consumer())
 ->bind($queueName, 'messages', 'message.new')
 ->listenTo($queueName, function($msg) use($key, $secret, $phoneNumber) {
 $msg = json_decode($msg);
 $urlString = 'https://rest.nexmo.com/sms/json?api_key=%s&api_secret=%s' .
 '&from=17088568489&to=%s&text=%s';
 $preparedMessage = urlencode($msg->comment);
 $url = sprintf($urlString, $key, $secret, $phoneNumber, $preparedMessage);
 $res = file_get_contents($url);
 $result = json_decode($res);
 $messageResult = $result->messages[0];
 echo "Message Result: " .
 ($messageResult->status === '0' ? 'Message Sent' : 'Message not sent')
 . PHP_EOL;
 return $messageResult->status === '0';
 })->listenAndWait();

  • 60. send text messages $queueName = 'messages_for_nexmo';
 
 (new Consumer())
 ->bind($queueName, 'messages', 'message.new')
 ->listenTo($queueName, function($msg) use($key, $secret, $phoneNumber) {
 $msg = json_decode($msg);
 $urlString = 'https://rest.nexmo.com/sms/json?api_key=%s&api_secret=%s' .
 '&from=17088568489&to=%s&text=%s';
 $preparedMessage = urlencode($msg->comment);
 $url = sprintf($urlString, $key, $secret, $phoneNumber, $preparedMessage);
 $res = file_get_contents($url);
 $result = json_decode($res);
 $messageResult = $result->messages[0];
 echo "Message Result: " .
 ($messageResult->status === '0' ? 'Message Sent' : 'Message not sent')
 . PHP_EOL;
 return $messageResult->status === '0';
 })->listenAndWait();

  • 61. Both queues get the message
  • 62.
  • 64. Yo dawg, let’s have a consumer publish
  • 65. Send an email After the text message
  • 66. Create a new Exchange
  • 67. Update text message consumer $publisher = new Publisher('sms');
 
 (new Consumer())
 ->bind($queueName, 'messages', 'message.new')
 ->listenTo($queueName, function($msg) use($key, $secret, $phoneNumber, $publisher) {
 // existing code
 $successful = $messageResult->status === '0';
 
 if ($successful) {
 $publisher->publish(‘sms.sent', ['message' => $msg->comment]);
 }
 
 return $successful;
 })->listenAndWait();

  • 68. Let’s write the email consumer And I’ll also show you how to easily test them
  • 69. Email Consumer (new Consumer())
 ->bind('send_email', 'emails', '*.send')
 ->bind('send_email', 'sms', '*.sent')
 ->listenTo('send_email', function($message){
 $msg = json_decode($message);
 mail('jasonlotito@gmail.com', 'MidwestPHP RabbitMQ Talk', $msg->message);
 echo 'Message sent: ' . $msg->message . PHP_EOL;
 return true;
 })->listenAndWait();
  • 70. Email consumer (new Consumer())
 ->bind('send_email', 'emails', '*.send')
 ->bind('send_email', 'sms', '*.sent')
 ->listenTo('send_email', function($message){
 $msg = json_decode($message);
 mail('jasonlotito@gmail.com', 'MidwestPHP RabbitMQ Talk', $msg->message);
 echo 'Message sent: ' . $msg->message . PHP_EOL;
 return true;
 })->listenAndWait();
  • 71.
  • 72. Now, let’s see it from the beginning
  • 73.
  • 75.
  • 76. Thank you. Review: joind.in/10558 #midwestphp #rabbitmq Questions? Feel free to stop and ask me, email, tweet, @jasonlotito@gmail.com