Listen to websocket events

At some point of your running websocket server, clients will connect and disconnect, and subscribe to a wamp topic to publish messages.

You may need to do something when one of these event happens.

Sandstone allows you to listen an event through the Silex event dispatcher.

Which event I can listen to

All these events are dispatched:

Event Event instance
ConnectionEvent::ON_OPEN ConnectionEvent
ConnectionEvent::ON_CLOSE ConnectionEvent
ConnectionEvent::ON_AUTHENTICATION WebsocketAuthenticationEvent
ConnectionEvent::ON_ERROR ConnectionErrorEvent
ConnectionEvent::ON_SUBSCRIBE WampEvent
ConnectionEvent::ON_UNSUBSCRIBE WampEvent
ConnectionEvent::ON_PUBLISH PublishEvent
ConnectionEvent::ON_RPC RPCEvent

Details of events

Event When is it called What can I do with it
ON_OPEN Someone connects to websocket server Retrieve some connection data with $event->getConn()->Websocket
ON_CLOSE Someone closed websocket connection same as below
ON_AUTHENTICATION Someone connected to websocket server and has been authenticated Retrieve authenticated user with $event->getUser() (returns Symfony UserInterface)
ON_ERROR An error has been triggered Retrieve the raised exception with $event->getError() (Returns an \Exception)
ON_SUBSCRIBE Someone subscribed to a topic Know which topic has been subscribed with $event->getTopic()
ON_UNSUBSCRIBE Someone unsubscribed to a topic same with unsubscription
ON_PUBLISH Someone published a message to a topic Listen to published messages on topics with $event->getEvent() to get message, $event->getTopic() to get topic
ON_RPC Remote procedure call Retrieve remote procedure call ID and parameters with $event->getId() and $event->getParams()

Listen to websocket events

I want to do something when someone connects to websocket server.

  • First, create the listener
<?php

use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Eole\Sandstone\Websocket\Event\ConnectionEvent;

class MyWebsocketListener implements EventSubscriberInterface
{
    public static function getSubscribedEvents()
    {
        return [
            ConnectionEvent::ON_OPEN => 'onOpen',
        ];
    }

    public function onOpen(ConnectionEvent $event)
    {
        // do something when someone connects

        // retrieve some connection data with $event->getConn()->Websocket;
        // which returns a ConnectionInterface from RatchetPHP
    }
}
  • Then, add in a Silex provider that implements EventListenerProviderInterface, in the method subscribe:
<?php

use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Pimple\Container;
use Silex\Api\EventListenerProviderInterface;

class MyProvider implements EventListenerProviderInterface
{
    public function subscribe(Container $app, EventDispatcherInterface $dispatcher)
    {
        $dispatcher->addSubscriber(new MyWebsocketListener());
    }
}

See more about EventListenerProviderInterface in Silex documentation about “Creating a provider”.

  • Finally, register this provider in your Sandstone application:
$app->register(new MyProvider());

Note: $app is your Sandstone application instance, created with $app = new Eole\Sandstone\Application().

See Full example of Sandstone application to have an example to how to bootstrap a Sandstone application.

Another example: listen to published messages

I want to display (for debugging purpose) all published messages in any topic.

I have to listen to the ConnectionEvent::ON_PUBLISH event:

  • First, create the listener
<?php

use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Eole\Sandstone\Websocket\Event\ConnectionEvent;
use Eole\Sandstone\Websocket\Event\PublishEvent;

class MyMessagePublishListener implements EventSubscriberInterface
{
    public static function getSubscribedEvents()
    {
        return [
            ConnectionEvent::ON_PUBLISH => 'onMessagePublish',
        ];
    }

    public function onMessagePublish(PublishEvent $event)
    {
        $message = $event->getEvent();
        $topic = $event->getTopic();

        echo "'$message' has been published in '$topic'", PHP_EOL;
    }
}
  • Then, register this listener
<?php

use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Pimple\Container;
use Silex\Api\EventListenerProviderInterface;

class MyProvider implements EventListenerProviderInterface
{
    public function subscribe(Container $app, EventDispatcherInterface $dispatcher)
    {
        $dispatcher->addSubscriber(new MyMessagePublishListener());
    }
}
  • Finally, register this provider in your Sandstone application:
$app->register(new MyProvider());

It should display in your websocket logs something like:

'Hello world' has been published in 'general/chat'

Event class diagram

Here is the events diagram, all attributes are inherited:

Sandstone websocket events DCM