Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reverb support #61

Open
jameswagoner opened this issue Apr 20, 2024 · 20 comments
Open

Reverb support #61

jameswagoner opened this issue Apr 20, 2024 · 20 comments
Labels
enhancement New feature or request flag Flag an issue for discussion in relevant contrib meeting

Comments

@jameswagoner
Copy link

Would be nice for out of the box support for Reverb or a guide if it just needs some tweaking of the YML.

I have tried various things to get a connection going and always ends up with a connection refused error.

@reynoldsalec
Copy link
Member

That would be awesome, I wonder if @yolcuiskender has played with Reverb at all? Know he's doing a bunch of cool stuff with Lando and various Laravel services...

@reynoldsalec reynoldsalec added enhancement New feature or request flag Flag an issue for discussion in relevant contrib meeting labels Apr 22, 2024
@yolcuiskender
Copy link
Collaborator

I haven't had the opportunity to use reverb yet, but I'm willing to give it a try in the next few days. Based on my initial understanding, I don't foresee encountering significant problems. However, if there are any specific aspects you'd like me to focus on or if you have any concerns, please feel free to let me know.

Looking forward to contributing to this issue.

@maikezan
Copy link

maikezan commented May 9, 2024

Any news about this? We are trying to set it up by ouserlves, but so far no success.
This is our current lando.yml:

name: test_app
recipe: laravel
config:
  webroot: public
  php: 8.2
  xdebug: true
  via: nginx
  database: mysql:8.0
  cache: redis
services:
  node:
    type: node:18
    scanner: false
    ports:
      - 3009:3009
  database:
    portforward: 3307
  cache:
    portforward: 32293
  appserver:
      config:
        server: .nginx/server.conf
  queue:
    type: php:8.2
    via: cli
    command: php artisan horizon
  reverb:
    type: php:8.2
    via: cli
    ssl: true
    command: php artisan reverb:start --debug
    overrides:
      ports:
        - 8080:8080
    networks:
      - network_default
networks:
  network_default:
    driver: bridge
tooling:
  npm:
    service: node
  node:
    service: node

Apparently reverb correctly starts to listen (looking at the logs) but we haven't found a way to make the app talk to the ws server. We always end up with failed connection:

WebSocket connection to 'wss://xxxxxx/app/wkvtwtt7uvf8kmmkjjgv?protocol=7&client=js&version=8.4.0-rc2&flash=false' failed: 
createWebSocket	@	pusher-js.js?v=20883fe9:3268

Following some other guide we also have configured a custom nginx.conf adding this:

.........
location /app {
        proxy_http_version 1.1;
        proxy_set_header Host $http_host;
        proxy_set_header Scheme $scheme;
        proxy_set_header SERVER_PORT $server_port;
        proxy_set_header REMOTE_ADDR $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";

        proxy_pass http://0.0.0.0:8080;
}
........

@jameswagoner
Copy link
Author

jameswagoner commented May 9, 2024 via email

@maikezan
Copy link

Yea there is something in the network part i'm missing. Amazingly i can succesfully connect to the websocket server now from outside the application (via POSTMAN) but not from within the app container, so there must be something up there.

@reynoldsalec
Copy link
Member

@maikezan are you using the correct hostname within the container environment for the wss server? For example, if you're trying to call the reverb service from another container in the app, it should be accessible as reverb.

@maikezan
Copy link

@maikezan are you using the correct hostname within the container environment for the wss server? For example, if you're trying to call the reverb service from another container in the app, it should be accessible as reverb.

this is something i need to test again. I think that was one of our first attempts and it didn't work. But we've made so many tests that i honestly need to rerun again with this and see if it works. Thanks for the suggestion

@maikezan
Copy link

So far no luck with using "reverb" as hostname.
We are still in this situation right now, where postman connect succesfully but laravel can't.

image

this is our current lando.yml for reverb:

reverb:
    type: php:8.3
    via: cli
    ports:
      - 8080:8080
    command: php artisan reverb:start --debug
    overrides:
      depends_on:
        cache:
          condition: service_started
        queue:
          condition: service_started

And .env file for reverb:

REVERB_APP_KEY=***
REVERB_APP_SECRET=***
REVERB_HOST="landotest.lndo.site"
REVERB_PORT=8080
REVERB_SCHEME=https```

@edouardgab
Copy link

Hi @maikezan !
Any chance you were able to resolve this? I am struggling with the same issue. Thanks !

@maikezan
Copy link

Hey @edouardgab , unfortunately i haven't resolved this. I'm currently using Laragon locally which works with some tweaks on the nginx configuration.
Basically adding this to the configuration:

location /app {
	proxy_http_version 1.1;
        proxy_set_header Host $http_host;
        proxy_set_header Scheme $scheme;
        proxy_set_header SERVER_PORT $server_port;
        proxy_set_header REMOTE_ADDR $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_pass http://127.0.0.1:8080;
}

I had tested this change in the lando nginx conf before, but failed to make it work. Maybe it can help you somehow?

@edouardgab
Copy link

edouardgab commented Sep 16, 2024

Hi @maikezan , Thansk for your reply !

Since my message, I was actually able to figure this out :) It was actually pretty simple once the right settings were found !

.env:

REVERB_SERVER_HOST=0.0.0.0
REVERB_SERVER_PORT=9201

REVERB_HOST=reverb
REVERB_PORT=9201
reverb:
    type: php:8.2
    via: cli
    command: php artisan reverb:start --debug
    portforward: true
    overrides:
      ports:
        - 9201:9201

I think everything you share was properly working, the issue was the necessity to properly listen to the events :

I did set it up in Postman to make it easier. Url :

First, connect to the websocket:

ws://myapp.lndo.site:9201/app/APP_ID

Then subscribe the the event

{
    "event": "pusher:subscribe",
    "data": {
        "auth": "",
        "channel": "App\\Events\\MY_EVENT"
    }
}

Hope this helps !

PS : I cannot look at the .lando.yml right now so I did by head. But it was fairly similar to what you did.

Edit : One small tip: look at the console of Reverb in Docket Desktop. That really help understanding what is going on.

@maikezan
Copy link

@edouardgab thank you for sharing your solution. I'll be giving it a try as soon as possible. i was sure we were "there" with the right approach.

@richt222
Copy link

This was a big help guys, thanks!

I can't seem to get it to work using a secure socket in the browser, but it does work in Postman. I guess because Chrome is objecting to the security certificate or similar. But works over an insecure socket in both the browser and Postman.

@roberttolton
Copy link

So I managed to get this working. SSL WebSockets between Laravel Echo and Laravel Reverb, through Lando.

Laravel .env:

REVERB_APP_ID=123456
REVERB_APP_KEY=something
REVERB_APP_SECRET=somethingelse
REVERB_HOST=myshop.lndo.site
REVERB_PORT=443
REVERB_SCHEME=http
REVERB_SERVER_PORT=8461
REVERB_SERVER_HOST=0.0.0.0

VITE_REVERB_APP_KEY="${REVERB_APP_KEY}"
VITE_REVERB_HOST="${REVERB_HOST}"
VITE_REVERB_PORT="${REVERB_PORT}"
VITE_REVERB_SCHEME="${REVERB_SCHEME}"

I am using a custom NGINX config in my Landofile, and exposing the reverb port.

Landofile .lando.yml:

name: myshop
recipe: laravel
keys:
  - id_rsa
config:
  php: '8.3'
  composer_version: '2.8.2'
  webroot: public
  via: nginx
  cache: redis
  config:
    vhosts: lando-config/nginx/default.conf
proxy:
  appserver_nginx:
    - myshop.lndo.site
services:
  appserver:
    overrides:
      extra_hosts:
        - 'host.docker.internal:host-gateway'
      expose:
        - '8461:8461'

The most important part of the NGINX config (aside from the proxies) was to add resolver 127.0.0.11; - and that is not a typo, that is indeed an 11 at the end and not just a 1.

Without that resolver, NGINX was not able to connect to the .internal hostname.

NGINX config /lando-config/nginx/default.conf:

server {

    listen 80 default_server;
    listen 443 ssl;

    server_name localhost;

    resolver 127.0.0.11;

    ssl_certificate           /certs/cert.crt;
    ssl_certificate_key       /certs/cert.key;
    ssl_verify_client         off;

    ssl_session_cache    shared:SSL:1m;
    ssl_session_timeout  5m;

    ssl_ciphers  HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers  on;

    port_in_redirect off;
    client_max_body_size 100M;

    root "{{LANDO_WEBROOT}}";
    index index.php index.html index.htm;

    location / {
         try_files $uri $uri/ /index.php$is_args$args;
    }

    location ~ \.php$ {
        try_files $uri /index.php =404;
        fastcgi_pass fpm:9000;
        fastcgi_index index.php;
        fastcgi_buffers 16 16k;
        fastcgi_buffer_size 32k;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_read_timeout 300; # Line added to default config
        include fastcgi_params;
    }

   # Laravel Reverb Proxies
  # https://thearkas.medium.com/how-to-set-up-nginx-for-laravel-reverb-the-laravels-websocket-server-5d89638d8366

   location ~ /app/(?<reverbkey>.*) { # variable reverbkey
     proxy_pass http://appserver.myshop.internal:8461/app/$reverbkey;
     proxy_http_version 1.1;
     proxy_set_header Host $http_host;
     proxy_set_header Scheme $scheme;
     proxy_set_header SERVER_PORT $server_port;
     proxy_set_header REMOTE_ADDR $remote_addr;
     proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
     proxy_set_header Upgrade $http_upgrade;
     proxy_set_header Connection "Upgrade";
   }

   location ~ ^/apps/(?<reverbid>[^/]+)/events$ { # variable reverbid
     proxy_pass http://appserver.myshop.internal:8461/apps/$reverbid/events;
     proxy_set_header Host $host;
     proxy_set_header X-Real-IP $remote_addr;
     proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
     proxy_set_header X-Forwarded-Proto $scheme;
   }

    location ~ /\.ht {
        deny all;
    }

    location /.well-known/acme-challenge/ {
        root /var/www/letsencrypt/;
        log_not_found off;
    }
}

The Echo setup is just regular.

echo.js:

import Echo from 'laravel-echo'
import Pusher from 'pusher-js'

window.Pusher = Pusher

window.Echo = new Echo({
    broadcaster: 'reverb',
    key: import.meta.env.VITE_REVERB_APP_KEY,
    wsHost: import.meta.env.VITE_REVERB_HOST,
    wsPort: import.meta.env.VITE_REVERB_PORT ?? 80,
    wssPort: import.meta.env.VITE_REVERB_PORT ?? 443,
    forceTLS: (import.meta.env.VITE_REVERB_SCHEME ?? 'https') === 'https',
    enabledTransports: ['ws', 'wss'],
})

@maikezan
Copy link

Hey @roberttolton !
Thanks for taking the time to provide such detailed solution!
I was wondering: in the NGINX conf, do you actually replace the and values manually with the env values?

@jameswagoner
Copy link
Author

Ohh that is slick! Could this get a PR for the masses?

@roberttolton
Copy link

@maikezan Which values are you referring to? Do you mean {{LANDO_WEBROOT}}? I don't do anything extra other than the configs above.

@jameswagoner I can try although I don't know how to recipe-ify the appserver.myshop.internal and port number used in the proxy config. Maybe it would be fine to just default to port 8080 like Reverb normally does. Then, there must be some variable or something for the other hostname I guess.

@maikezan
Copy link

@maikezan Which values are you referring to? Do you mean {{LANDO_WEBROOT}}? I don't do anything extra other than the configs above.

@jameswagoner I can try although I don't know how to recipe-ify the appserver.myshop.internal and port number used in the proxy config. Maybe it would be fine to just default to port 8080 like Reverb normally does. Then, there must be some variable or something for the other hostname I guess.

Sorry i haven't specified actually :|
i meant those reverbkey and id references in the 2 location entries:

 location ~ /app/(?<reverbkey>.*) { # variable reverbkey
     proxy_pass http://appserver.myshop.internal:8461/app/$reverbkey;

@roberttolton
Copy link

I guess those aren't strictly necessary since the destination URI ends up being the same as the input.

@maikezan
Copy link

Going to give it another try as soon as possible. Thanks meanwhile !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request flag Flag an issue for discussion in relevant contrib meeting
Projects
Development

No branches or pull requests

7 participants