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

Laravel reverb not working with SSL on production with apache #288

Closed
pranavmankar opened this issue Dec 24, 2024 · 5 comments
Closed

Laravel reverb not working with SSL on production with apache #288

pranavmankar opened this issue Dec 24, 2024 · 5 comments

Comments

@pranavmankar
Copy link

Reverb Version

1.0

Laravel Version

11.29

PHP Version

8.3.12

Description

I am using Let's Encrypt SSL. PHP 8.3.12 — Laravel 11.29.0

In terminal after running: php artisan reverb:start --debug
It shows: Starting server on 0.0.0.0:8080 (example.com).

Getting this error in the console of the receive-notification blade file.

WebSocket connection to 'wss://localhost:8080/app/m0ym3fxag51pkwyz7n6u?protocol=7&client=js&version=8.4.0-rc2&flash=false' failed:

Steps To Reproduce

My event code

class SendNotification implements ShouldBroadcastNow
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

     public $msg;

    public function __construct($msg)
    {
        //
        $this->msg = $msg;

    }

    /**
     * Get the channels the event should broadcast on.
     *
     * @return array<int, \Illuminate\Broadcasting\Channel>
     */
    public function broadcastOn()
    {
        return new Channel('noti');
    }

    public function broadcastAs()
    {
        return "notify";
    }

    public function broadcastWith()
    {
        return [
            "message" => $this->msg
        ];
    }
}

.env file

REVERB_APP_ID=APP_ID
REVERB_APP_KEY=APP_key
REVERB_APP_SECRET=APP_SECRET
REVERB_HOST="example.com"
REVERB_SERVER_PORT=8080
REVERB_PORT=443
REVERB_SCHEME=https

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

echo.js file

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'],
});

receive-notification.blade.php JavaScript code

@vite('resources/js/app.js')
<script type="module">
   window.Echo.channel("noti").
    listen(".notify", (e) => {
      console.log(e);
    } )
</script>

virtual host conf file

<VirtualHost *:80>
    ServerAdmin [email protected]
    DocumentRoot "/www/wwwroot/example.com/public"
    ServerName ea68ca5f.example.com
    ServerAlias example.com www.example.com
    #errorDocument 404 /404.html
    ErrorLog "/www/wwwlogs/example.com-error_log"
    CustomLog "/www/wwwlogs/example.com-access_log" combined
    #HTTP_TO_HTTPS_START
    <IfModule mod_rewrite.c>
        RewriteEngine on
        RewriteCond %{SERVER_PORT} !^443$
        RewriteRule (.*) https://%{SERVER_NAME}$1 [L,R=301]
    </IfModule>
    #HTTP_TO_HTTPS_END

    #DENY FILES
     <Files ~ (\.user.ini|\.htaccess|\.git|\.env|\.svn|\.project|LICENSE|README.md)$>
       Order allow,deny
       Deny from all
    </Files>
    
    #PHP
    <FilesMatch \.php$>
            SetHandler "proxy:unix:/tmp/php-cgi-83.sock|fcgi://localhost"
    </FilesMatch>
    
    #PATH
    <Directory "/www/wwwroot/example.com/public">
        SetOutputFilter DEFLATE
        Options FollowSymLinks
        AllowOverride All
        Require all granted
        DirectoryIndex index.php index.html index.htm default.php default.html default.htm
    </Directory>

    
</VirtualHost>
<VirtualHost *:443>
    ServerAdmin [email protected]
    DocumentRoot "/www/wwwroot/example.com/public"
    ServerName SSL.example.com
    ServerAlias www.example.com example.com 
    #errorDocument 404 /404.html
    ErrorLog "/www/wwwlogs/example.com-error_log"
    CustomLog "/www/wwwlogs/example.com-access_log" combined
    
    #SSL
    SSLEngine On
    SSLCertificateFile /www/server/panel/vhost/cert/example.com/fullchain.pem
    SSLCertificateKeyFile /www/server/panel/vhost/cert/example.com/privkey.pem
    SSLCipherSuite EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5
    SSLProtocol All -SSLv2 -SSLv3 -TLSv1
    SSLHonorCipherOrder On
    
    
    #PHP
    <FilesMatch \.php$>
            SetHandler "proxy:unix:/tmp/php-cgi-83.sock|fcgi://localhost"
    </FilesMatch>
    

    #DENY FILES
     <Files ~ (\.user.ini|\.htaccess|\.git|\.svn|\.project|LICENSE|README.md)$>
       Order allow,deny
       Deny from all
    </Files>

    #PATH
    <Directory "/www/wwwroot/example.com/public">
        SetOutputFilter DEFLATE
        Options FollowSymLinks
        AllowOverride All
        Require all granted
        DirectoryIndex index.php index.html index.htm default.php default.html default.htm
    </Directory>
</VirtualHost>
ProxyPreserveHost On
<Location /app>
        ProxyPass ws://0.0.0.0:8080/app
        ProxyPassReverse ws://0.0.0.0:8080/app
</Location>
<Location /apps>
        ProxyPass http://0.0.0.0:8080/apps
        ProxyPassReverse http://0.0.0.0:8080/apps
</Location>
@kailasb10
Copy link

SSLProtocol

Facing the same issue. It works with the "root" user.

@pranavmankar
Copy link
Author

SSLProtocol

Facing the same issue. It works with the "root" user.

Could you please explain how you did with the root user? I also have root access. I also tried using root access but it didn't work.

@pranavmankar
Copy link
Author

I just ran npm install and npm run build on production, and the problem is solved.

@kailasb10
Copy link

SSLProtocol

Facing the same issue. It works with the "root" user.

Could you please explain how you did with the root user? I also have root access. I also tried using root access but it didn't work.

sudo -u apache php artisan reverb:start --debug

Running above is not working.

I've configured it with SSL (Self Signed Certificate)

Configure Echo:

import Echo from "laravel-echo";

import Pusher from "pusher-js";
window.io = require("socket.io-client");

window.Pusher = Pusher;

window.Echo = new Echo({
    broadcaster: "reverb",
    key: process.env.MIX_REVERB_APP_KEY,
    wsHost: process.env.MIX_REVERB_HOST,
    wsPort: process.env.MIX_REVERB_PORT,
    wssPort: process.env.MIX_REVERB_PORT,
    forceTLS: (process.env.MIX_REVERB_SCHEME ?? "https") === "https",
    enabledTransports: ["ws", "wss"],
    // added for private channel
    host: HOST_URL + `broadcasting/auth`, // Adjust to match your host and port
    auth: {
        headers: {
            "X-CSRF-TOKEN": document.querySelector('meta[name="csrf-token"]').getAttribute("content"),
        },
    },
});

broadcasting.php

"connections" => [
       "reverb" => [
           "driver" => "reverb",
           "key" => env("REVERB_APP_KEY"),
           "secret" => env("REVERB_APP_SECRET"),
           "app_id" => env("REVERB_APP_ID"),
           "options" => [
               "host" => env("REVERB_HOST"),
               "port" => env("REVERB_PORT", 443),
               "scheme" => env("REVERB_SCHEME", "https"),
               "useTLS" => env("REVERB_SCHEME", "https") === "https",
               "curl_options" => [
                   CURLOPT_SSL_VERIFYHOST => 0,
                   CURLOPT_SSL_VERIFYPEER => 0,
               ],
           ],
           "client_options" => [
               "verify" => env("APP_ENV") !== "local",
           ],
       ],

       "redis" => [
           "driver" => "redis",
           "connection" => "default",
       ],

       "log" => [
           "driver" => "log",
       ],

       "null" => [
           "driver" => "null",
       ],
   ],

reverb.php

"servers" => [
        "reverb" => [
            "host" => env("REVERB_SERVER_HOST", "0.0.0.0"),
            "port" => env("REVERB_SERVER_PORT", 8080),
            "hostname" => env("REVERB_HOST"),
            "options" => [
                "tls" => [
                    "local_cert" => env("LOCAL_CERT"),
                    "local_pk" => env("LOCAL_PK"),
                    "passphrase" => env("PASSPHRASE"),
                ],
            ],
            "max_request_size" => env("REVERB_MAX_REQUEST_SIZE", 10_000),
            "scaling" => [
                "enabled" => env("REVERB_SCALING_ENABLED", false),
                "channel" => env("REVERB_SCALING_CHANNEL", "reverb"),
                "server" => [
                    "url" => env("REDIS_URL"),
                    "host" => env("REDIS_HOST", "127.0.0.1"),
                    "port" => env("REDIS_PORT", "6379"),
                    "username" => env("REDIS_USERNAME"),
                    "password" => env("REDIS_PASSWORD"),
                    "database" => env("REDIS_DB", "0"),
                ],
            ],
            "pulse_ingest_interval" => env("REVERB_PULSE_INGEST_INTERVAL", 15),
            "telescope_ingest_interval" => env("REVERB_TELESCOPE_INGEST_INTERVAL", 15),
        ],
    ],

ssl.conf

<IfModule mod_proxy.c>
    ProxyRequests Off
    SSLProxyEngine On
    SSLProxyCheckPeerName off

    # Ensure WebSocket protocol is forwarded correctly
    RewriteEngine on
    RewriteCond %{HTTP:UPGRADE} ^Websocket$ [NC]
    RewriteCond %{HTTP:CONNECTION} Upgrade$ [NC]
    RewriteRule /app/(.*) wss://localhost:8080/app/$1 [P]

    ProxyPass /apps https://0.0.0.0:8080/apps
    ProxyPassReverse /apps https://0.0.0.0:8080/apps
</IfModule>

BroadcastOnUi.php

class BroadcastOnUi implements ShouldBroadcastNow
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    public $message;
    public $result;
    public $dateFrom;
    public $dateTo;
    /**
     * Create a new event instance.
     *
     * @return void
     */
    public function __construct($message, $result, $dateFrom, $dateTo)
    {
        $this->message = $message;
        $this->result = $result;
        $this->dateFrom = $dateFrom;
        $this->dateTo = $dateTo;
    }

    /**
     * Get the channels the event should broadcast on.
     *
     * @return \Illuminate\Broadcasting\Channel|array
     */
    public function broadcastOn()
    {
        return new Channel("MyChannel");
    }
}

app.js

let myChannel= Echo.channel("MyChannel." + event.detail.ref);
myChannel.listen("BroadcastOnUi", (data) => {
    if (data.result == "ok") {
       ......
    } else {
        .....
    }
});

@joedixon
Copy link
Collaborator

Hi there,

Thanks for reporting the problem you are encountering, but it looks like this is a question which may be better suited for a support channel. We only use this issue tracker for reporting bugs with the library itself. If you have a question on how to use functionality provided by this repository you can try one of the following channels:

However, this issue will not be locked and everyone is still free to discuss solutions to your problem!

Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants