driftphp/demo

Websocket events don't work on remote host, only local host

iorsa opened this issue · 6 comments

iorsa commented

Hi,

I have a question that is relative to drift/websocket-bundle and driftphp/demo package.

In order to get successfull connection between websocket server (based on Ratchet library) and websocket client (based on js code in browser) http host should match in both places.

Since in driftphp/demo ws host is set to 0.0.0.0 in both places, it's only possible to have successfull websocket connection only on local host (where both server and client should be launched).

I wanted to launch driftphp/demo on remote host and changed the affected lines, but I got an error, while running websocket container in docker.

Here is what I've changed.

In both .env files (in root app directory and in docker-compose directory) I've added WEBSOCKET_HOST env value with my hostname.

In websocket-entrypoint.sh file I sourced .env file and used WEBSOCKET_HOST env value as http host for websocket server.
Before:
php bin/console websocket:run 0.0.0.0:8000 --route=events --exchange=events --env=prod
After:

. .env
php bin/console websocket:run "$WEBSOCKET_HOST":8000 --route=events --exchange=events --env=prod

In Drift/views/index.twig file I changed default ws http host value in js code.
Before:
const conn = new WebSocket('ws://0.0.0.0:{{ websocket_port }}/events');
After:
const conn = new WebSocket('ws://{{ websocket_host }}:{{ websocket_port }}/events');

In events.html file I've also changed the default ws http host value in js code, though I guess it's not used anywhere (I've not properly searched though).
Before:
const conn = new WebSocket('ws://0.0.0.0:1234/events');
After:
const conn = new WebSocket('ws://' + window.location.hostname + ':1234/events');

Here's the error in websocket_1 container that I have in Docker:

websocket_1         | 2020-06-15T20:01:28+00:00 [debug] Notified event "console.command" to listener "Symfony\Component\HttpKernel\EventListener\DebugHandlersListener::configure".
websocket_1         | 
websocket_1         | >  
websocket_1         | >  ReactPHP Websocket Server for DriftPHP
websocket_1         | >    by Marc Morera (@mmoreram)
websocket_1         | >  
websocket_1         | >  Host: myHostNameHere.com
websocket_1         | >  Port: 8000
websocket_1         | >  Environment: prod
websocket_1         | >  Debug: enabled
websocket_1         | >  Routes: events
websocket_1         | >  Exchanges subscribed: events
websocket_1         | >  
websocket_1         | 
websocket_1         | 2020-06-15T20:01:28+00:00 [error] Error thrown while running command "websocket:run 'myHostNameHere.com:8000' --route=events --exchange=events --env=prod". Message: "Could not connect to localhost:5672: Network unreachable."
websocket_1         | 2020-06-15T20:01:28+00:00 [debug] Notified event "console.error" to listener "Symfony\Bundle\FrameworkBundle\EventListener\SuggestMissingPackageSubscriber::onConsoleError".
websocket_1         | 2020-06-15T20:01:28+00:00 [debug] Notified event "console.error" to listener "Symfony\Component\Console\EventListener\ErrorListener::onConsoleError".
websocket_1         | 2020-06-15T20:01:28+00:00 [debug] Command "websocket:run 'myHostNameHere.com:8000' --route=events --exchange=events --env=prod" exited with code "101"
websocket_1         | 2020-06-15T20:01:28+00:00 [debug] Notified event "console.terminate" to listener "Symfony\Component\Console\EventListener\ErrorListener::onConsoleTerminate".
websocket_1         | 
websocket_1         | In AbstractClient.php line 235:
websocket_1         |                                                              
websocket_1         |   [Bunny\Exception\ClientException (101)]                    
websocket_1         |   Could not connect to localhost:5672: Network unreachable.  
websocket_1         |                                                              
websocket_1         | 
websocket_1         | Exception trace:
websocket_1         |   at /var/www/vendor/bunny/bunny/src/Bunny/AbstractClient.php:235
websocket_1         |  Bunny\AbstractClient->getStream() at /var/www/vendor/bunny/bunny/src/Bunny/Async/Client.php:195
websocket_1         |  Bunny\Async\Client->connect() at /var/www/var/cache/prod/ContainerOM5DHun/getAmqp_EventBusClientService.php:16
websocket_1         |  require() at /var/www/var/cache/prod/ContainerOM5DHun/Drift_KernelProdDebugContainer.php:161
websocket_1         |  ContainerOM5DHun\Drift_KernelProdDebugContainer->load() at /var/www/var/cache/prod/ContainerOM5DHun/getAmqp_EventBusChannelService.php:13
websocket_1         |  require() at /var/www/var/cache/prod/ContainerOM5DHun/Drift_KernelProdDebugContainer.php:161
websocket_1         |  ContainerOM5DHun\Drift_KernelProdDebugContainer->load() at /var/www/var/cache/prod/ContainerOM5DHun/getAsyncAdapter2Service.php:25
websocket_1         |  require() at /var/www/var/cache/prod/ContainerOM5DHun/Drift_KernelProdDebugContainer.php:161
websocket_1         |  ContainerOM5DHun\Drift_KernelProdDebugContainer->load() at /var/www/var/cache/prod/ContainerOM5DHun/getAsyncAdapter2Service.php:12
websocket_1         |  ContainerOM5DHun\Drift_KernelProdDebugContainer->{closure}() at /var/www/var/cache/prod/ContainerOM5DHun/AMQPAdapter_239a9c8.php:62
websocket_1         |  Closure->__invoke() at /var/www/var/cache/prod/ContainerOM5DHun/AMQPAdapter_239a9c8.php:62
websocket_1         |  AMQPAdapter_239a9c8->subscribe() at /var/www/vendor/drift/event-bus-bundle/Subscriber/EventBusSubscriber.php:64
websocket_1         |  Drift\EventBus\Subscriber\EventBusSubscriber->subscribeToExchanges() at /var/www/vendor/drift/websocket-bundle/Console/RunWebsocket.php:120
websocket_1         |  Drift\Websocket\Console\RunWebsocket->execute() at /var/www/vendor/symfony/console/Command/Command.php:255
websocket_1         |  Symfony\Component\Console\Command\Command->run() at /var/www/vendor/symfony/console/Application.php:930
websocket_1         |  Symfony\Component\Console\Application->doRunCommand() at /var/www/vendor/symfony/framework-bundle/Console/Application.php:97
websocket_1         |  Symfony\Bundle\FrameworkBundle\Console\Application->doRunCommand() at /var/www/vendor/symfony/console/Application.php:264
websocket_1         |  Symfony\Component\Console\Application->doRun() at /var/www/vendor/symfony/framework-bundle/Console/Application.php:83
websocket_1         |  Symfony\Bundle\FrameworkBundle\Console\Application->doRun() at /var/www/vendor/symfony/console/Application.php:140
websocket_1         |  Symfony\Component\Console\Application->run() at /var/www/bin/console:45
websocket_1         | 
websocket_1         | websocket:run [--route ROUTE] [--exchange EXCHANGE] [-h|--help] [-q|--quiet] [-v|vv|vvv|--verbose] [-V|--version] [--ansi] [--no-ansi] [-n|--no-interaction] [-e|--env ENV] [--no-debug] [--] <command> <path>
websocket_1         | 
dockercompose_websocket_1 exited with code 101

It looks like I'm missing something or doing it wrong. Is it possible to resolve?

iorsa commented

I've missed to add first lines in websocket docker logs, though it is same problem there, when event-bus:infra:create command is executed.

Connected to POSTGRES!
Waiting AMQP. Slepping
Waiting AMQP. Slepping
Waiting AMQP. Slepping
Connected to AMQP!
2020-06-16T04:39:50+00:00 [debug] Notified event "console.command" to listener "Symfony\Component\HttpKernel\EventListener\DebugHandlersListener::configure".
2020-06-16T04:39:50+00:00 [error] Error thrown while running command "event-bus:infra:create --exchange events --force". Message: "Could not connect to localhost:5672: Network unreachable."
2020-06-16T04:39:50+00:00 [debug] Notified event "console.error" to listener "Symfony\Bundle\FrameworkBundle\EventListener\SuggestMissingPackageSubscriber::onConsoleError".
2020-06-16T04:39:50+00:00 [debug] Notified event "console.error" to listener "Symfony\Component\Console\EventListener\ErrorListener::onConsoleError".
2020-06-16T04:39:50+00:00 [debug] Command "event-bus:infra:create --exchange events --force" exited with code "101"
2020-06-16T04:39:50+00:00 [debug] Notified event "console.terminate" to listener "Symfony\Component\Console\EventListener\ErrorListener::onConsoleTerminate".

In AbstractClient.php line 235:
                                                             
  [Bunny\Exception\ClientException (101)]                    
  Could not connect to localhost:5672: Network unreachable.  
                                                             

Exception trace:
  at /var/www/vendor/bunny/bunny/src/Bunny/AbstractClient.php:235
 Bunny\AbstractClient->getStream() at /var/www/vendor/bunny/bunny/src/Bunny/Async/Client.php:195
 Bunny\Async\Client->connect() at /var/www/var/cache/dev/ContainerMobhIaM/getAmqp_EventBusClientService.php:16
 require() at /var/www/var/cache/dev/ContainerMobhIaM/Drift_KernelDevDebugContainer.php:161
 ContainerMobhIaM\Drift_KernelDevDebugContainer->load() at /var/www/var/cache/dev/ContainerMobhIaM/getAmqp_EventBusChannelService.php:13
 require() at /var/www/var/cache/dev/ContainerMobhIaM/Drift_KernelDevDebugContainer.php:161
 ContainerMobhIaM\Drift_KernelDevDebugContainer->load() at /var/www/var/cache/dev/ContainerMobhIaM/getAsyncAdapter2Service.php:25
 require() at /var/www/var/cache/dev/ContainerMobhIaM/Drift_KernelDevDebugContainer.php:161
 ContainerMobhIaM\Drift_KernelDevDebugContainer->load() at /var/www/var/cache/dev/ContainerMobhIaM/getAsyncAdapter2Service.php:12
 ContainerMobhIaM\Drift_KernelDevDebugContainer->{closure}() at /var/www/var/cache/dev/ContainerMobhIaM/AMQPAdapter_239a9c8.php:27
 Closure->__invoke() at /var/www/var/cache/dev/ContainerMobhIaM/AMQPAdapter_239a9c8.php:27
 AMQPAdapter_239a9c8->getName() at /var/www/vendor/drift/event-bus-bundle/Console/InfrastructureCreateCommand.php:92
 Drift\EventBus\Console\InfrastructureCreateCommand->execute() at /var/www/vendor/symfony/console/Command/Command.php:255
 Symfony\Component\Console\Command\Command->run() at /var/www/vendor/symfony/console/Application.php:930
 Symfony\Component\Console\Application->doRunCommand() at /var/www/vendor/symfony/framework-bundle/Console/Application.php:97
 Symfony\Bundle\FrameworkBundle\Console\Application->doRunCommand() at /var/www/vendor/symfony/console/Application.php:264
 Symfony\Component\Console\Application->doRun() at /var/www/vendor/symfony/framework-bundle/Console/Application.php:83
 Symfony\Bundle\FrameworkBundle\Console\Application->doRun() at /var/www/vendor/symfony/console/Application.php:140
 Symfony\Component\Console\Application->run() at /var/www/bin/console:45

event-bus:infra:create [--exchange EXCHANGE] [-f|--force] [-h|--help] [-q|--quiet] [-v|vv|vvv|--verbose] [-V|--version] [--ansi] [--no-ansi] [-n|--no-interaction] [-e|--env ENV] [--no-debug] [--] <command>

2020-06-16T04:39:51+00:00 [debug] Notified event "console.command" to listener "Symfony\Component\HttpKernel\EventListener\DebugHandlersListener::configure".

I guess it is related to docker network communication between containers. Since I'm trying to run websocket server at specific host, it's somehow cannot communicate to localhost rabbitmq socket.

@iorsa thanks for that feedback!

Seems that the problem is that containers are not being able to connect between them, yes. Can you share the '.env' file?

iorsa commented

@mmoreram sure!

It's almost same as default:

SERVER_PORT=8000
WEBSOCKET_HOST=myHostNameHere.com
WEBSOCKET_PORT=1234

DBAL_DRIVER=postgres
DBAL_HOST=localhost
DBAL_PORT=5432
DBAL_USER=root
DBAL_PASSWORD=root
DBAL_DATABASE=demo

AMQP_HOST=localhost
AMQP_COMMANDS_QUEUE=commands
AMQP_EVENTS_EXCHANGE=events

ENV=prod

I only added WEBSOCKET_HOST=myHostNameHere.com there.

Btw, I've forgotten to mention that I changed few other files in order to apply this new env value inside index twig template.

In Drift/config/services.yml file I added new line with string $websocketHost: "%env(WEBSOCKET_HOST)%" right after string $websocketPort: "%env(WEBSOCKET_PORT)%" line.

In Src/Controller/IndexController.php file I added private $websocketHost string value the same way as you did with $websocketPort, so it should be possible to invoke it in request with websocket_host parameter.

Attaching all changed files in zip.

driftphp_demo_changes_for_remote_ws.zip

demo/.env
demo/docker/websocket-entrypoint.sh
demo/Drift/config/services.yml
demo/Drift/views/index.twig
demo/src/Controller/IndexController.php

Try with this env:

SERVER_PORT=8000
WEBSOCKET_HOST=myHostNameHere.com
WEBSOCKET_PORT=1234

DBAL_DRIVER=postgres
DBAL_HOST=demo_postgres
DBAL_PORT=5432
DBAL_USER=root
DBAL_PASSWORD=root
DBAL_DATABASE=demo

AMQP_HOST=demo_amqp
AMQP_COMMANDS_QUEUE=commands
AMQP_EVENTS_EXCHANGE=events

ENV=prod

@iorsa I've updated the repository with the default .env file updated.

My apoplogies for the issue.
As soon as it works again, feel free to close the issue here :D

iorsa commented

It's fully working now with my remote hostname and provided above setup. Thanks for fast response!