Skip to content

Latest commit

 

History

History
154 lines (115 loc) · 5.06 KB

File metadata and controls

154 lines (115 loc) · 5.06 KB

Remote Procedure Call Setup

Every remote procedure call (RPC) in GosWebSocketBundle has its own "network namespace" in order to dispatch requests to the correct command.

In your Symfony application, RPCs are setup as services. This allows you full control of what to do with the class, whether its a mailer or an entity manager.

If you are new to services, please see Symfony: Service Container

Overview

  • Create the service class
  • Register your service with Symfony
  • Register your service with GosPubSubRouterBundle

Step 1: Create the Service Class

Your service is a PHP class which must implement Gos\Bundle\WebSocketBundle\RPC\RpcInterface.

For each method you want to expose as a RPC handler, the method must use the following signature:

<?php

use Gos\Bundle\WebSocketBundle\Router\WampRequest;
use Ratchet\ConnectionInterface;

public function myHandler(ConnectionInterface $connection, WampRequest $request, $params);
  • The $connection is the websocket connection for the user executing the RPC call
  • The $request is the request data for the RPC call (similar to the Symfony\Component\HttpFoundation\Request object in controllers)
  • The $params is an array of parameters for the RPC call (similar to the $_POST data of a HTTP request)
<?php

namespace App\Websocket\Rpc;

use Gos\Bundle\WebSocketBundle\Router\WampRequest;
use Gos\Bundle\WebSocketBundle\RPC\RpcInterface;
use Ratchet\ConnectionInterface;

final class AcmeRpc implements RpcInterface
{
    /**
     * Adds the params together
     *
     * Note: $connection isn't used here, but contains the connection of the user making this request.
     *
     * @param ConnectionInterface $connection
     * @param WampRequest $request
     * @param array $params
     *
     * @return array
     */
    public function sum(ConnectionInterface $connection, WampRequest $request, $params)
    {
        return ['result' => array_sum($params)];
    }

    /**
     * Name of the RPC handler, used by the PubSub router.
     *
     * @return string
     */
    public function getName()
    {
        return 'acme.rpc';
    }
}

To return a result from the procedure, simply return anything other than false or null. If you pass an array, its automatically converted to a JSON Object.

If you return false or null, it will return an error to the client, informing them the procedure call did not work correctly.

Step 2: Register your service with Symfony

For an application based on the Symfony Standard structure, you can register services in either your app/config/services.yml file or your bundle's Resources/config/services.yml file. For an application based on Symfony Flex, use the config/services.yaml file.

RPC handlers must be tagged with the gos_web_socket.rpc tag to be correctly registered. Note that when autowiring is enabled, your service will be automatically tagged.

services:
    app.websocket.rpc.acme:
        class: App\Websocket\Rpc\AcmeRpc
        tags:
            - { name: gos_web_socket.rpc }

For other formats, please review the Symfony Documentation.

Step 3: Register your service with GosPubSubRouterBundle

Now that you have created your RPC service, you must now link the path with your service. sample/sum will refer to the service you've created.

If not already created, you should create a routing file for the GosPubSubRouterBundle configuration. For Symfony Standard, you should use either app/config/pubsub/routing.yml or your bundle's Resources/config/pubsub/routing.yml. For Symfony Flex, you should use config/pubsub/routing.yaml.

acme_rpc:
    channel: sample/{method}
    handler: 'acme.rpc' #related to the getName() or your RPC service
    requirements:
        method: "[a-z_]+"

Next, you will need to include the new resource in the bundle's configuration to ensure the PubSub router is set up correctly.

gos_web_socket:
    server:
        port: 8080
        host: 127.0.0.1
        router:
            resources:
                - '%kernel.project_dir%/config/pubsub/routing.yaml'

From here, each call that matches with this pattern will handled by the AcmeRpc class.

Similar to Symfony's Routing component, you can define multiple routes in a single file.

acme_abc_rpc:
    channel: sample/{method}
    handler: 'acme.method_abc.rpc'
    requirements:
        method: "method_a|method_b|method_c"
            
acme_de_rpc:
    channel: sample/{method}
    handler: 'acme.method_de.rpc'
    requirements:
        method: "method_d|method_e"

Step 4: Call a RPC function with the JavaScript client

You can now call your RPC function using the JavaScript client.

e.g.

session.call("sample/sum", {"term1": 2, "term2": 5}).then(
    function (result) {
        console.log("RPC Valid!", result);
    },
    function (error, desc) {
        console.log("RPC Error", error, desc);
    }
);

For more information on the JavaScript Client the bundle, please see Client Side Setup