Vinelab / minion

A Simplified Client for WAMP v2 (Web Application Messaging Protocol) with command line support - PHP WebSocket Made Easy
MIT License
126 stars 16 forks source link

Connection issue with autobahn.js #1

Closed mohammedibrahim closed 9 years ago

mohammedibrahim commented 9 years ago

Dears,

I have followed the instructure in the Read Me to make it work with laravel but it's not working

I got these errors in the command line and it's repeated

2014-12-06T16:51:31.7175210 info [Thruway\Transport\PawlTransportProvider 11798] Starting Transport 2014-12-06T16:51:31.7187670 info [Thruway\Transport\PawlTransportProvider 11798] Could not connect: Connection refused

I also tried to open a connection using autobahn.js but it gives me this issues in the browser console

WebSocket connection to 'ws://127.0.0.1:8080/' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED

Mulkave commented 9 years ago

What are you using to run the Router ? i.e. Crossbar ? and what port are you running the router on ?

mohammedibrahim commented 9 years ago

I fixed it. The issue was that I run a client without running a server that client should listen to. Thanks very much.

Mulkave commented 9 years ago

Glad to hear. Enjoy!

prbaron commented 9 years ago

Hello, I have the same problem.

I am using Laravel 4.2. I pasted all code and all commandes needed. I have the config file in the app/config/packages/vinelab/minion/minion.php.

<?php

return [

    /*
    |--------------------------------------------------------------------------
    | Router Realm
    |--------------------------------------------------------------------------
    |
    | The realm that the router should use.
    |
    */
    'realm'     => 'arato',

    /*
    |--------------------------------------------------------------------------
    | Router Host
    |--------------------------------------------------------------------------
    |
    | The IP or hostname that the router should run under.
    |
    */
    'host'      => '127.0.0.1',

    /*
    |--------------------------------------------------------------------------
    | Router Port
    |--------------------------------------------------------------------------
    |
    | The port that should be used by the router.
    |
    */
    'port'      => 8080,

    /*
    |--------------------------------------------------------------------------
    | Auto-registered Providers
    |--------------------------------------------------------------------------
    |
    | The providers listed here will be automatically registered on the
    | session start of the router, in return their role is to register RPCs,
    | subscribe and publish to topics and pretty much whatever an Internal Client does.
    |
    */
    'providers' => [

        // 'MyApp\Providers\MyAwesomeProvider',

    ],

    'debug'     => true,

];

However, I have not used any crossbar.io server. Should I need it ? Or is Minion the crossbar server ? Do I really need a Provider ? I want to use Minion as server to clients communications.

Mulkave commented 9 years ago

@prbaron kindly note that Minion is not a WAMP server, it's another client that provides the convenience of multiple providers, so you still need to run crossbar (or any other WAMP server) so that Minion can connect to. There is a crossbar config file provided by Minion so all you have to do is:

prbaron commented 9 years ago

@Mulkave Thank you !

I do not have data from my javascript client...

my laravel controller

class AlertsController extends Controller {
    public function index($userId = null)
    {
        Minion::register(function (Client $client) {
            // publish
            $client->publish('i.am.here', ['name' => 'mr.minion']);
        });
        return true;
    }
}

my javascript file

var connection = new autobahn.Connection({
        url   : 'ws://127.0.0.1:9090',
        realm : 'minion'
    });

    connection.onopen = function (session) {
        session.subscribe('i.am.here', function (msg) {
            console.log("i am here", msg);
        });
    };

    connection.open();

Here what I did : 1) launch crossbar (crossbar start --cbdir ./vendor/vinelab/minion/.crossbar) 2) launch minion (php artisan minion:run) 3) run my webserver (grunt serve, from yeoman generator-angular)

No console log.

Do I have to create a Provider ? Can the Controller publish a message ?

Best regards

Mulkave commented 9 years ago

@prbaron your controller is always registering the callback but never running it.

The thing that you need to know is that once you run minion:run what has been registered/subscribed cannot change at run-time, and in that case you have to use Providers instead of this Controller.

Try the following from a provider and you should get this to work:

namespace App;

use Vinelab\Minion\Provider;

class AlertsProvider extends Provider
{
    public function boot()
    {
        $this->publish('i.am.here', [], ['name' => 'mr.minion']);
    }
}

Then register App\AlertsProvider in the providers array of minion.php

The boot() method will run once the provider has initialized and your autobahn javascript should receive the action as expected.

Another thing to note here is that you are sending key-value params (assoc array) which can only be received by on the kwArgs parameter of session.subscribe('topic', args, kwArgs) which means you will have to change the subscribe to the following:

session.subscribe('i.am.here', function (args, msg) {
        console.log("i am here", msg);
});
prbaron commented 9 years ago

Is there no way for me to send data from my controller ? This is what I would like.

Here is my use case : I have a todo application where several users can add todos one the same list. When somebody add a todo, i would like that everybody get notified about this new todo.

So when the client send a POST request to AlertsController.store(), I thought to send a publish event from the controller with the newly created todo in argument.

is it possible ? Or should I send 2 requests from javascripts clients (one in HTTP to add the new TODO and if success, the publish message through websocket to all other clients ?)

Mulkave commented 9 years ago

Unfortunately, this is not possible at the moment, but your use case is interesting enough to be investigated further, because in fact there's not a relation between the session running Minion and Laravel's controllers but will dig deeper for some sort of a connection between them.

For now, what is recommended to do is rely on one of either Websocket or HTTP since both can perform the same tasks and barely have anything different except session/cookies stuff. Your provider can play the controller role.