Satori RTM Connection.
Access the RTM Service on the connection level to connect to the RTM Service, send and receive PDUs Uses WebSocket client to connect to RTM.
Does not handle any possible exceptions from the WS client.
Observable class.
Allows to extend any struct with ability to Fire events and ability to listen for any events.
RTM client.
The RtmClient class is the main entry point to manage the WebSocket connection from the PHP SDK to RTM.
Use the RtmClient class to create a client instance from which you can publish messages and subscribe to channels, create separate Subscription objects for each channel to which you want to subscribe.
RtmClient has a single-threaded model. This model imposes some limitations:
RTM Client allows to use Event-Based model for Events. Use client.on<Event> function to continuously processing events.
Base syntax: $client->onEvent($callback_function);
Example:
<?php
$client = new RtmClient(ENDPOINT, APP_KEY);
$client->onConnected(function () {
echo 'Connected to Satori RTM and authenticated as ' . ROLE . PHP_EOL;
})->onError(function ($type, $error) {
echo "Type: $type; Error: $error[message] ($error[code])" . PHP_EOL;
});
$client->connect();
Each event handler returns $client object, so you can register callbacks continuously.
You can register multiple callbacks on the same event:
$client = new RtmClient(ENDPOINT, APP_KEY);
$client->onConnected(function () {
echo 'Callback 1';
});
$client->onConnected(function () {
echo 'Callback 2';
});
$client->connect();
There are 4 base events:
onConnected()
onDisconnected($code, $message)
onAuthenticated()
onError($type, $error)
You can specify role to get role-based permissions (E.g. get an access to Subscribe/Publish to some channels) when connecting to the endpoint. Follow the link to get more information: https://www.satori.com/docs/using-satori/authentication
Use \RtmClient\Auth\RoleAuth to authenticate using role-based authentication:
$options = array(
'auth' => new RtmClient\Auth\RoleAuth(ROLE, ROLE_SECRET_KEY),
);
$client = new RtmClient(ENDPOINT, APP_KEY, $options);
RTM client allows to subscribe to channels:
$client->subscribe('animals', function ($ctx, $type, $data) {
print_r($data);
});
Check the \RtmClient\Subscription\Subscription class to get more information about the possible options.
A subscription callback is called when the following subscription events occur:
SUBSCRIBED - after getting confirmation from Satori RTM about subscription
UNSUBSCRIBED - after successful unsubscribing
DATA - when getting rtm/subscription/data from Satori RTM
INFO - when getting rtm/subscription/info message
ERROR - on every rtm/subscription/error or rtm/subscribe/error
You should specify callback when creating a new subscription. Example:
use RtmClient\Subscription\Events;
$callback = function ($ctx, $type, $data) {
switch ($type) {
case Events::SUBSCRIBED:
echo 'Subscribed to: ' . $ctx['subscription']->getSubscriptionId() . PHP_EOL;
break;
case Events::UNSUBSCRIBED:
echo 'Unsubscribed from: ' . $ctx['subscription']->getSubscriptionId() . PHP_EOL;
break;
case Events::DATA:
foreach ($data['messages'] as $message) {
if (isset($message['who']) && isset($message['where'])) {
echo 'Got animal ' . $message['who'] . ': ' . json_encode($message['where']) . PHP_EOL;
} else {
echo 'Got message: ' . json_encode($message) . PHP_EOL;
}
}
break;
case Events::ERROR:
echo 'Subscription failed. ' . $err['error'] . ': ' . $err['reason'] . PHP_EOL;
break;
}
};
$subscription = $client->subscribe('animals', $callback, array(
'filter' => "SELECT * FROM `animals` WHERE who = 'zebra'",
));
Because of RtmClient has a single-threaded model you should alternate read and write operations
Simple publish with ack example. We publish message and require acknowledge from Sator RTM:
$client = new RtmClient(ENDPOINT, APP_KEY);
$client->publish(CHANNEL, 'test message', function ($ack) {
echo 'Got ack from Satori RTM';
});
$client->tcpReadSync(); // Wait for reply from Satori RTM
In case if you do not want to wait too much time on reading use timeout:
$client = new RtmClient(ENDPOINT, APP_KEY);
$client->publish(CHANNEL, 'test message', function ($ack) {
echo 'Got ack from Satori RTM';
});
$client->tcpReadSync(2); // Wait for incoming message for 2 seconds only
If you await multiple replies use \RtmClient\RtmClient::waitAllReplies()
$client = new RtmClient(ENDPOINT, APP_KEY);
$client->publish(CHANNEL, 'message', function ($ack) {
echo 'Got ack 1 from Satori RTM';
});
$client->publish(CHANNEL, 'message-2', function ($ack) {
echo 'Got ack 2 from Satori RTM';
});
$client->read(CHANNEL, function ($data) {
echo 'Got read data from Satori RTM';
});
$client->waitAllReplies(); // Also you can specify wait timeout in seconds
echo 'Done!';
// Output:
// Got ack 1 from Satori RTM
// Got ack 2 from Satori RTM
// Got read data from Satori RTM
// Done!
Also there is an Async mode. Reading in this mode means, that you will not be blocked if there are no incoming messages in socket:
use RtmClient\WebSocket\ReturnCode as RC;
$client = new RtmClient(ENDPOINT, APP_KEY);
$client->publish(CHANNEL, 'test message', function ($ack) {
echo 'Got ack from Satori RTM';
});
$code = $client->tcpReadAsync();
switch ($code) {
case RC::READ_OK:
echo 'Read incoming message';
break;
case RC::READ_WOULD_BLOCK:
echo 'There are no messages in socket at this moment';
break;
default:
echo 'Another return code';
}
If you subscribe to the channels and want to publish messages in the same time you can use tcpReadAsync or Async helpers: \RtmClient\RtmClient::sockReadIncoming() or \RtmClient\RtmClient::sockReadFor()
$messages_count = 0;
$client = new RtmClient(ENDPOINT, APP_KEY);
$client->subscribe(CHANNEL, function ($ctx, $type, $data) use (&$messages_count) {
if ($type == Events::DATA) {
foreach ($data['messages'] as $message) {
echo 'Got message: ' . json_encode($message) . PHP_EOL;
$messages_count++;
}
}
});
while (true) {
$client->sockReadFor(2); // Read possible messages for 2 seconds
$client->publish(ANOTHER_CHANNEL, time(), function() {
echo 'Sent time' . PHP_EOL;
});
$client->publish(MY_STAT_CHANNEL, $messages_count, function() {
echo 'Sent messages count' . PHP_EOL;
});
}
An RtmClient instance is a one-time connection. It means that you cannot continue using client after connection is dropped.
To make a new connection to Satori RTM you can clone previous client:
$new_client = clone $old_client;
$new_client->connect();
All your callbacks will be moved to the new client. After calling connect
client will establish a new connection to Satori RTM.
Note that you need to restore your subscriptions manually.
See reconnects examples.