GeniusesOfSymfony / WebSocketBundle

:part_alternation_mark: Websocket server for Symfony applications (powered by Ratchet), includes a Autobahn.JS based JavaScript client
MIT License
609 stars 140 forks source link

DI services #413

Closed smokezp closed 4 years ago

smokezp commented 4 years ago

Hi, I have issue with dependency injection of your services. I cant get any service from container. For example PusherInterface, or this way $this->get('gos_web_socket.pusher.wamp') . I'm using symfony 5.7. Is it compatibility issue?

mbabker commented 4 years ago

There isn't a Symfony 5.7 release. Do you mean 5.0.7?

I'm assuming you are trying to get the pusher from a controller. Remember that newer Symfony versions do not receive the full DI container, they only receive partial containers with specified services (see https://symfony.com/doc/current/service_container/service_subscribers_locators.html), so if you are intending to use the container to pull services they need to be defined as part of that subscriber (though you should prefer dependency injection over pulling things from the container).

smokezp commented 4 years ago

Ok. thanks. I'll check your link

smokezp commented 4 years ago

(though you should prefer dependency injection over pulling things from the container).

I cant inject pusher. It says: Cannot autowire argument $pusher of \"App\\Controller\\Controller::someAction()\": it references interface \"Gos\\Bundle\\WebSocketBundle\\Pusher\\PusherInterface\" but no such service exists. You should maybe alias this interface to one of these existing services: \"gos_web_socket.pusher.wamp.data_collector\", \"gos_web_socket.pusher.wamp.data_collector.inner\".", "class": "Symfony\\Component\\DependencyInjection\\Exception\\RuntimeException",

Why service is missing?

mbabker commented 4 years ago

Did you enable the pusher in the bundle configuration? If not, the service won’t be available.

As multiple pushers are supported, there isn’t anything in the bundle that arbitrarily maps either pusher service to the PusherInterface for autowiring support. You can set this alias in your application or manually configure the argument in your services file.

stipic commented 4 years ago

I have same problem. I cant inject pusher, and i have pusher defined in bundle configuration

Same error:

Cannot resolve argument $conversationHandler of "App\Controller\ConversationController::conversation()": Cannot autowire service "App\Service\ConversationHandler": argument "$zmqPusher" of method "__construct()" references interface "Gos\Bundle\WebSocketBundle\Pusher\PusherInterface" but no such service exists. You should maybe alias this interface to one of these existing services: "gos_web_socket.pusher.amqp.data_collector", "gos_web_socket.pusher.amqp.data_collector.inner".

My config:

gos_web_socket:
    server:
        port: 5510
        host: 127.0.0.1
        router:
           resources:
               - '%kernel.project_dir%/config/pubsub.yml'
        origin_check: false
    client:
        firewall: main
        session_handler: app_session_db_storage

    pushers:
        amqp:
            enabled: true # Flag to enable this pusher
            host: 127.0.0.1 # Host address for the AMQP server
            port: 5672 # Port the AMQP server is listening on
            login: guest # Required, the login for the AMQP server
            password: guest # Required, the password for the AMQP server
            vhost: / # The virtual host on the host, default `/`
            read_timeout: 0 # Timeout for incoming activity in seconds, default 0
            write_timeout: 0 # Timeout for outgoing activity in seconds, default 0
            connect_timeout: 0 # Connection timeout in seconds, default 0
            queue_name: gos_websocket # The name of the queue for messages, default `gos_websocket`
            exchange_name: gos_websocket_exchange # The name of the exchange for messages, default `gos_websocket`

Can you PLEASE make one simple example of DI in documentation.

I have my own service that i autowire on controller and in that service i want to push messages.

mbabker commented 4 years ago
services:
    # default configuration for services in *this* file
    _defaults:
        autowire: true      # Automatically injects dependencies in your services.
        autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
        bind:
            $amqpPusher: '@gos_web_socket.pusher.amqp'

That binds the gos_web_socket.pusher.amqp to any $amqpPusher variable found when autowiring.

services:
    App\Service\ConversationHandler:
        arguments:
            '$amqpPusher': '@gos_web_socket.pusher.amqp'

That explicitly sets the variable for constructor injection on a service.

Can you PLEASE make one simple example of DI in documentation.

You're welcome to send a pull request to add it. I didn't because I wasn't trying to copy Symfony's documentation into the bundle to explain how to manually define services where autowiring can't work 100% of the time. For the pushers, https://symfony.com/doc/current/service_container/autowiring.html#dealing-with-multiple-implementations-of-the-same-type and https://symfony.com/doc/current/service_container/autowiring.html#fixing-non-autowireable-arguments are the references for how to get around this autowiring issue.

stipic commented 4 years ago

Thank you for fast answser, When I manage to fix my problems i promise i will give my best to make docs better from my expirience with this bundle.

I will try now your advice :)