harveyslash
harveyslash

Reputation: 6012

Ratchet, push integration, not working

I am using ratchet along with laravel.

This is my main socket server:

<?php
/**
 * Created by PhpStorm.
 * User: harshvardhangupta
 * Date: 27/05/16
 * Time: 1:40 PM
 */
use App\Http\Controllers\SocketController;

require './vendor/autoload.php';
$loop   = React\EventLoop\Factory::create();
$pusher = new SocketController();

// Listen for the web server to make a ZeroMQ push after an ajax request
$context = new React\ZMQ\Context($loop);
$pull = $context->getSocket(ZMQ::SOCKET_PULL);
$pull->bind('tcp://127.0.0.1:5555'); // Binding to 127.0.0.1 means the only client that can connect is itself
$pull->on('message', array($pusher, 'onBlogEntry'));

// Set up our WebSocket server for clients wanting real-time updates
$webSock = new React\Socket\Server($loop);
$webSock->listen(8080, '0.0.0.0'); // Binding to 0.0.0.0 means remotes can connect
$webServer = new Ratchet\Server\IoServer(
    new Ratchet\Http\HttpServer(
        new Ratchet\WebSocket\WsServer(
            new Ratchet\Wamp\WampServer(
                $pusher
            )
        )
    ),
    $webSock
);

$loop->run();

and this is my socket controller:

<?php
namespace App\Http\Controllers;
use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;
use Ratchet\Wamp\Topic;
use Ratchet\Wamp\WampServerInterface;

class SocketController implements WampServerInterface
{
    /**
     * A lookup of all the topics clients have subscribed to
     */
    protected $subscribedTopics = array();

    public function onSubscribe(ConnectionInterface $conn, $topic) {
        echo"on";
        $this->subscribedTopics[$topic->getId()] = $topic;
    }

    /**
     * @param string JSON'ified string we'll receive from ZeroMQ
     */
    public function onBlogEntry($entry) {
        $entryData = json_decode($entry, true);

        // If the lookup topic object isn't set there is no one to publish to
        if (!array_key_exists($entryData['category'], $this->subscribedTopics)) {
            return;
        }

        $topic = $this->subscribedTopics[$entryData['category']];

        // re-send the data to all the clients subscribed to that category
        $topic->broadcast($entryData);
    }


    public function onUnSubscribe(ConnectionInterface $conn, $topic) {
    }
    public function onOpen(ConnectionInterface $conn) {
        echo"open";

    }
    public function onClose(ConnectionInterface $conn) {
        echo "close";
    }

    /* The rest of our methods were as they were, omitted from docs to save space */
    /**
     * If there is an error with one of the sockets, or somewhere in the application where an Exception is thrown,
     * the Exception is sent back down the stack, handled by the Server and bubbled back up the application through this method
     * @param  ConnectionInterface $conn
     * @param  \Exception $e
     * @throws \Exception
     */
    function onError(ConnectionInterface $conn, \Exception $e)
    {
        // TODO: Implement onError() method.
    }

    /**
     * An RPC call has been received
     * @param \Ratchet\ConnectionInterface $conn
     * @param string $id The unique ID of the RPC, required to respond to
     * @param string|Topic $topic The topic to execute the call against
     * @param array $params Call parameters received from the client
     */
    function onCall(ConnectionInterface $conn, $id, $topic, array $params)
    {
        // TODO: Implement onCall() method.
    }

    /**
     * A client is attempting to publish content to a subscribed connections on a URI
     * @param \Ratchet\ConnectionInterface $conn
     * @param string|Topic $topic The topic the user has attempted to publish to
     * @param string $event Payload of the publish
     * @param array $exclude A list of session IDs the message should be excluded from (blacklist)
     * @param array $eligible A list of session Ids the message should be send to (whitelist)
     */
    function onPublish(ConnectionInterface $conn, $topic, $event, array $exclude, array $eligible)
    {
        // TODO: Implement onPublish() method.
    }
}

There is another script that calls :

        $context = new ZMQContext();
        $socket = $context->getSocket(ZMQ::SOCKET_PUSH, 'my pusher');
        $socket->connect("tcp://localhost:5555");
        $socket->send("okay");
        die("okay");

First I run the client code in a browser(note, its the same machine as server):

<script src="http://autobahn.s3.amazonaws.com/js/autobahn.min.js"></script>
<script>
    var conn = new ab.Session('ws://localhost:8080',
        function() {
            conn.subscribe('kittensCategory', function(topic, data) {
                // This is where you would add the new article to the DOM (beyond the scope of this tutorial)
                console.log('New article published to category "' + topic + '" : ' + data.title);
            });
        },
        function() {
            console.warn('WebSocket connection closed');
        },
        {'skipSubprotocolCheck': true}
    );
</script>

this connection works, as I am able to see the log message in my server console output. However, when I call the script that is supposed to send data to the client, the client does not receive it. No log messages are produced in client browser.

Upvotes: 1

Views: 1479

Answers (2)

mitchken
mitchken

Reputation: 800

To explain why your configuration was not working.

You are sending the message "okay" to the pushserver from the piece of code you have

 $context = new ZMQContext();
 $socket = $context->getSocket(ZMQ::SOCKET_PUSH, 'my pusher');
 $socket->connect("tcp://localhost:5555");
 $socket->send("okay"); -- HERE --
 die("okay");

and in this piece of code you receive that call, this method expects you to send the $entryData['category'] as the 'channel' you want to send the data to

public function onBlogEntry($entry) {
    $entryData = json_decode($entry, true);

    // If the lookup topic object isn't set there is no one to publish to
    if (!array_key_exists($entryData['category'], $this->subscribedTopics)) {
        return;
    }

    $topic = $this->subscribedTopics[$entryData['category']];

    // re-send the data to all the clients subscribed to that category
    $topic->broadcast($entryData);
}

Although the client is connected to the kittensCategory

conn.subscribe('kittensCategory', function(topic, data){

What you actually should do is send a correct object to the pushserver so that the websocket would know where to send the data to.

$entryData = array(
    'category' => 'kittensCategory',
    'data'    =>  'hello'
);

this code would send your data to the kittensCategory

If you need more information please let me know

Upvotes: 2

harveyslash
harveyslash

Reputation: 6012

After trying this for a few hours, I read somewhere to enable debug using ab.debug(true,true).

After that, I see that messages are indeed getting received.

Upvotes: 0

Related Questions