beyondcode / laravel-websockets

Websockets for Laravel. Done right.
https://beyondco.de/docs/laravel-websockets
MIT License
5.07k stars 612 forks source link

WS - ERR_SSL_PROTOCOL_ERROR - Laravel Forge - Project without Authentication #501

Closed mho22 closed 7 months ago

mho22 commented 4 years ago

I have an issue with Websockets and my actuel websocket test project. No problems with my local project. But when it comes to deploy on my Laravel Forge Server I get the :

app.js:41145 WebSocket connection to 'wss://my-domain:6002/app/my-app-key?protocol=7&client=js&version=7.0.0&flash=false' failed: Error in connection establishment: net::ERR_SSL_PROTOCOL_ERROR

I think it is important to indicate that I do not have implemented a Authentication on my project.

My configuration is as follows :

broadcasting.php

'pusher' => [
            'driver' => 'pusher',
            'key' => env('PUSHER_APP_KEY'),
            'secret' => env('PUSHER_APP_SECRET'),
            'app_id' => env('PUSHER_APP_ID'),
            'options' => [
                'cluster' => env('PUSHER_APP_CLUSTER'),
                'encrypted' => false,
                'host' => '127.0.0.1',
                'port' => 6001,
                'scheme' => 'http',
            ],
        ],

websockets.php

'apps' => [
        [
            'id' => env('PUSHER_APP_ID'),
            'name' => env('APP_NAME'),
            'key' => env('PUSHER_APP_KEY'),
            'secret' => env('PUSHER_APP_SECRET'),
            'enable_client_messages' => false,
            'enable_statistics' => true,
        ],
    ],

bootstrap.js

window.Pusher = require('pusher-js');

window.Echo = new Echo({
    broadcaster: 'pusher',
    key: process.env.MIX_PUSHER_APP_KEY,
    cluster: process.env.MIX_PUSHER_APP_CLUSTER,
    wsHost: window.location.hostname,
    wsPort: process.env.MIX_APP_ENV == 'local' ? 6001 : 6002,
    wssPort: process.env.MIX_APP_ENV == 'local' ? 6001 : 6002,
    enabledTransports: ['ws', 'wss'],
    disableStats: true,
    encrypted: false,
});

I of course followed the tutorial from Alex Bouma and added port 6002 in the Network Tab

WS | 6002 | Allow | Any

And implemented to daemons in the Deamon Tab

id | php artisan horizon | /home/forge/mydomain | forge | 1
id | php artisan websockets:serve | /home/forge/mydomain | forge | 1

Nginx config file :

# FORGE CONFIG (DO NOT REMOVE!)
include forge-conf/my-domain/before/*;
server {
    listen 80;
    listen [::]:80;
    server_name my-domain;
    server_tokens off;
    root /home/forge/my-domain/public;
    # FORGE SSL (DO NOT REMOVE!)
    # ssl_certificate;
    # ssl_certificate_key;
    #ssl_protocols TLSv1.2;
    #ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384;
    #ssl_prefer_server_ciphers on;
    #ssl_dhparam /etc/nginx/dhparams.pem;
    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-XSS-Protection "1; mode=block";
    add_header X-Content-Type-Options "nosniff";
    index index.html index.htm index.php;
    charset utf-8;
    # FORGE CONFIG (DO NOT REMOVE!)
    include forge-conf/my-domain/server/*;
    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }
    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }
    access_log off;
    error_log  /var/log/nginx/my-domain-error.log error;
    error_page 404 /index.php;
    location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
        fastcgi_index index.php;
        include fastcgi_params;
    }
    location ~ /\.(?!well-known).* {
        deny all;
    }
}
server {
    listen 6002;
    listen [::]:6002;
    server_name my-domain;
    root /home/forge/my-domain/public;
    ssl_protocols TLSv1.2;
    ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384;
    ssl_prefer_server_ciphers on;
    ssl_dhparam /etc/nginx/dhparams.pem;
    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-XSS-Protection "1; mode=block";
    add_header X-Content-Type-Options "nosniff";
    index index.html index.htm index.php;
    charset utf-8;
    # FORGE CONFIG (DO NOT REMOVE!)
    include forge-conf/my-domain/server/*;
    location / {
        proxy_pass             http://127.0.0.1:6001;
        proxy_read_timeout     60;
        proxy_connect_timeout  60;
        proxy_redirect         off;
        # Allow the use of websockets
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }
    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }
    access_log off;
    error_log  /var/log/nginx/my-domain-error.log error;
    error_page 404 /index.php;
    location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
        fastcgi_index index.php;
        include fastcgi_params;
    }
    location ~ /\.(?!well-known).* {
        deny all;
    }
}
# FORGE CONFIG (DO NOT REMOVE!)
include forge-conf/my-domain/after/*;

I faced another problem [ minor ] with my Without Authentication Project, I couldn't access /laravel-websockets. I decided to extend the WebSocketsServiceProvider and add :

<?php

namespace App\Providers;

use Illuminate\Support\Facades\Route;
use Illuminate\Support\Facades\Gate;
use BeyondCode\LaravelWebsockets\WebSocketsServiceProvider;
use BeyondCode\LaravelWebSockets\Dashboard\Http\Controllers\AuthenticateDashboard;
use BeyondCode\LaravelWebSockets\Dashboard\Http\Controllers\DashboardApiController;
use BeyondCode\LaravelWebSockets\Dashboard\Http\Controllers\SendMessage;
use BeyondCode\LaravelWebSockets\Dashboard\Http\Controllers\ShowDashboard;
use BeyondCode\LaravelWebSockets\Dashboard\Http\Middleware\Authorize as AuthorizeDashboard;
use BeyondCode\LaravelWebSockets\Statistics\Http\Controllers\WebSocketStatisticsEntriesController;

class WebSocketServiceProvider extends WebSocketsServiceProvider
{
    protected function registerRoutes()
    {
        Route::prefix(config('websockets.path'))->group(function () 
        {
            Route::get('/', ShowDashboard::class);
            Route::get('/api/{appId}/statistics', [DashboardApiController::class,  'getStatistics']);
            Route::post('auth', AuthenticateDashboard::class);
            Route::post('event', SendMessage::class);

            Route::post('statistics', [WebSocketStatisticsEntriesController::class, 'store']);
        });

        return $this;
    }

    protected function registerDashboardGate()
    {
        Gate::define('viewWebSocketsDashboard', function ($user = null) 
        {
            return true;
        });
    }
}

config.app.php

App\Providers\WebSocketServiceProvider::class

But, of course, error appears when trying to connect to port 6002:

WebSocket connection to 'ws://my-domain:6001/app/my-app-key?protocol=7&client=js&version=4.3.1&flash=false' failed: Error in connection establishment: net::ERR_CONNECTION_TIMED_OUT

And I can't access statistics:

GET http://my-domain/laravel-websockets/api/my-app-id/statistics 500 (Internal Server Error)

rminossi commented 3 years ago

Hi, you have a solution?

mho22 commented 3 years ago

Not yet, unfortunately, I put it aside for the moment, I'll try to figure it out in the next weeks, if I can.