Important

You are browsing documentation for version 6.1 of OroCommerce, supported until 2029. Read the documentation for the latest LTS version to get up-to-date information.

See our Release Process documentation for more information on the currently supported and upcoming releases.

Create a Topic and a Handler for Publishing and Subscribing 

As discussed in the section on WebSockets Architecture, all WebSocket messages in Oro applications are published to a particular topic. Clients subscribe to the topics they are interested in.

This is the PubSub pattern, part of the Web Application Message Protocol subprotocol of the WebSockets protocol. It provides a standard for coordinating real-time messaging between program components in loosely-coupled, microservice-based architectures.

OroSyncBundle provides a router as part of the WebSocket server that receives messages for topics from publishers and distributes the messages to subscribed clients.

To create a new topic for WebSocket messages in the Oro application, perform two main tasks:

  • Declare topic with its route.

  • Create one or more handlers to serve events related to this topic.

Declare Topic and Its Routing 

To declare a route for the topic, create a websocket_routing.yml file in the Resources/config/oro directory of your bundle, with the following contents:

oro_sync.ping:                      # unique machine name of your topic in format "%extension_alias%.topic_name"
    channel: 'oro/ping'             # url of your topic channel
    handler:
        callback: 'oro_sync.ping'   # machine name of topic handler

You can declare parameterized routes as well, e.g.,:

oro_email.event:
    channel: 'oro/email_event/{user_id}/{organization_id}'
    handler:
        callback: 'oro_email.event'
    requirements:
        user_id:
            pattern: '\d+' # regular expression
        organization_id:
            pattern: '\d+'

You can get parameters using getAttributes() from the WampRequest $request argument in your topic handler. You can find more information about routing in the documentation of GosWebSocketBundle.

Create and Declare Topic Handlers 

Topic handler is called by the WebSocket server router whenever one of the following events occurs:

  • Client has subscribed

  • Client has unsubscribed

  • Client has published a message

Each topic handler decides what to do with the event based on its logic. For example, in onSubscribe(), we can decide whether to allow subscription, and in onPublish(), we can broadcast the given message either to all subscribers or just to a restricted list.

Topic handler must implement Gos\Bundle\WebSocketBundle\Topic\TopicInterface and be declared as a service with the gos_web_socket.topic tag, e.g.,:

oro_sync.topic.websocket_ping:
    class: Oro\Bundle\SyncBundle\Topic\WebsocketPingTopic
    arguments:
        - 'oro_sync.ping'
        - '@logger'
        - '%oro_sync.websocket_ping.interval%'
    tags:
        - { name: gos_web_socket.topic }

The getName() method of the topic handler must return its machine name which is used in the websocket_routing.yml file for the handler.callback configuration option.

OroSyncBundle provides an abstract class Oro\Bundle\SyncBundle\Topic\AbstractTopic and two out-of-box implementations of topic handlers for common purposes:

  • Oro\Bundle\SyncBundle\Topic\BroadcastTopic broadcasts every published message to all subscribers. It is required for simple topics like oro_sync.maintenance which just informs about maintenance mode activation.

  • Oro\Bundle\SyncBundle\Topic\SecuredTopic checks if a client is allowed to subscribe to the topic. It broadcasts every published message to all subscribers. It is required for topics like oro_email.event which informs users about new emails.

Therefore, if your topic handler does not need complex logic, you can use the existing handlers, e.g.,:

oro_sync.topic.maintenance:
    class: Oro\Bundle\SyncBundle\Topic\BroadcastTopic
    arguments:
        - 'oro_sync.maintenance'
    tags:
        - { name: gos_web_socket.topic }

Subscribe to the Topic Messages 

To subscribe a backend client for the topic messages, you can create your own topic handler (as described in the section above) and use its onPublish() method to perform any necessary tasks when a message is published to the topic.

To subscribe a frontend client to and unsubscribe it from the topic, use the subscribe and unsubscribe methods of the orosync/js/sync component, e.g.,:

import sync from 'orosync/js/sync';

sync.subscribe('oro/ping', () => {
    console.log('Received message from oro/ping topic');
});