Clients/PHP

PHP Client Class

The SAPO_Broker class abstracts all the low-level complexity of the SAPO Broker and gives the developer a simple to use high-level API to build event consumers and producers.

It will work with at least PHP 4.3.0 but PHP >5.2.x is recomended. Minimum PHP requirements are the  mbstring extension and  streams support for socket communications. Most standard PHP distributions have these.

This class is event driven and provides the  main loop for your program. Running an event consumer with this class requires only 3 simple steps:

  • Initializing the class $broker=new SAPO_Broker;
  • Subscribing the desired event topics $broker->subscribe(...);
  • Running the main loop $broker->consumer();

A very simple (but complete) consumer can look like this:

include('classes/broker.php');
$broker=new SAPO_Broker;
$broker->subscribe('/sapo/homepage/visits',NULL,"processEvent");
$broker->consumer();

function processEvent($payload) {
  echo "Someone has visited the Homepage\n";
  echo $payload."\n";
  }

Lets look into each step in detail now:

Class initialization

The first thing to do is initializing the class. You can do this at any stage in your code. It as simple as:

$broker=new SAPO_Broker;

Initialization options

When initializing the SAPO_Broker class, you can provide a series of parameters to tune your preferences. All of them are optional. These are:

server

Defines the IP address of the broker agent to which connect.

If this parameter is not supplied then a series of tests are conducted to provide auto-discovery for the nearest agent:

  • The environment variable SAPO_BROKER_SERVER is checked. If it exists, then it will be used.
  • Tries to connect to the localhost (127.0.0.1) IP. Will be used if successful.
  • Check for the existence of a /etc/world_map.xml file. Picks a random agent from it. Tries to connect. Uses it if successful (otherwise repeats the step 2 more times).
  • Uses the last resort DNS name broker.bk.sapo.pt which is a round robin record to a few agents.

port

TCP port in which the Broker is listening for clients. Default is 3332.

debug

Setting debug to true will output a lot of useful information for the developer. Default is false.

timeout

Maximum time (in seconds) for inactivity (sent or received data) after which the connection drops and reconnects. Default is 5 minutes.

locale

 Locale setting used in multibyte functions. Default is pt_PT.

force_expat

Force the XML parser to use  expat. Default is false.

force_dom

Force the XML parser to use native PHP  DOM support. Default is false.

If neither force_dom or force_dom are specified (default behavior), the DOM parser has priority and will be used if available.

The parameters are passed inside an array structure like this:

$opts=array('debug'=>TRUE
            'server'=>'10.135.0.1'
            'force_dom'=>TRUE);

$broker=new SAPO_Broker($opts);

Subscribing a topic

You may subscribe as many topics as you wish before entering the main loop. For each subscription you must provide the topic name, the callback function to handle the incoming events from that topic, and an optional array of parameters the the subscription. This is the syntax:

$broker->subscribe('/topic/path',$opts,"callbackUserFunc");

Topic name

A topic is a namespace in the form of a filesystem path. Each topic is related to certain kind of events. Topic producers are advised to follow a logical hierarchy like this /unit/platform/kind/subkind/...

For instance this topic /sapo/blogs/activity/post sends events each time a user from the  SAPO Blogs posts an article.

And this /sapo/blogs/activity/session sends events each time a user logs on.

You can also subscribe multiple topics with only one subscription using  regular expressions. For instance, subscribing this /sapo/blogs/activity/.* will get you events from both topics above, plus anything after /sapo/blogs/activity/...

Subscription options

destination_type

There are 3 supported types of destination:

  • TOPIC (default)
  • QUEUE
  • TOPIC_AS_QUEUE

TOPIC type topics are fire and forget events. The produced events are broadcasted across the cloud and one or more consumers can read those events in parallel. Events can be missed from the consumers if there is a problem. Think an FM radio station and many listeners tuned in. This is actually the most common use-case and the default setting.

QUEUE type topics implement true persistent and secure queues across the cloud. Each produced event is guaranteed only to be read by one consumer and leaves the queue only when it's acknowledged by both ends. Use cases for queues are online payment events, a registration process, etc.

TOPIC_AS_QUEUE is very similar to the above but the events are produced as normal TOPIC types and fired and forgotten, only the consumers act like QUEUEers. This is very useful for load balancing scenarios. For instance suppose you have a normal TOPIC type with loads of messages per second which you need to process into a SQL database. You can have 2 or more TOPIC_AS_QUEUE subscribed consumers processing those events and the cloud guarantees the equal distribution of unique events to each, so in practice you're distributing the topic load to N consumers. As there's no acknowledge in the producer you can also mix TOPIC with TOPIC_AS_QUEUE subscriptions, the cloud will handle this just fine.

Callback function

This is the name of the function used to receive the payload from the events. This function will be called by the main loop each time a new event arrives and it's supposed to process the payload in any way to user wishes.

If the callback function is inside a class you can use this syntax:

$broker->subscribe('/topic/path',$opts,array("Class_Name","callbackUserFunc"));

Each time the function is called, 3 parameters are passed to it's arguments, namely:

function callbackFunc($payload,$topic,$message_id) {};

payload

This includes the event payload which can be pretty much anything the producer defines, an XML message or plain text.

topic

The topic to which the event refers. This is useful if you're using wildcard subscriptions.

message_id

Each event has a MessageId. This is it.

Advanced usage

Periodic calls

For flexibility you can add your own periodic calls to the main loop. They will be executed regardless of the incoming traffic in your subscribed topics. This allows more complex programs to be written with the SAPO_Broker APIs.

Just call add_callback as many times as you wish before the main loop, like this:

$broker->add_callback(array("sec"=>5),"periodicCall");

Again you can use the array("Class_Name","periodicCall") syntax if your function lives inside a class.

In the input arguments you can use sec (seconds) or usec (microseconds) to define the time interval for which the function is executed.

Here's a complete code example for better understanding.

References