Beyondcode Laravel Websockets:失败:在建立连接之前关闭WebSocket

时间:2019-10-05 11:30:53

标签: laravel websocket echo pusher

本地websockets运行得很顺畅,但在生产过程中,我总是得到标题中的错误。

我正在使用websocket包的一些背景信息:beyondcode / laravel-websockets。我正在与主管一起运行'php artisan websockets:serve --port = 6004'。我还确保端口6004打开。

在生产环境中,我尝试使用SSL和不使用SSL的设置,都在标题中出现了错误。

使用SSL进行的设置:

我的回声设置:

window.Echo = new Echo({
    broadcaster: 'pusher',
    key: process.env.MIX_PUSHER_APP_KEY,
    wsHost: window.location.hostname,
    wsPort: 6004,
    wssPort: 6004,
    disableStats: true,
    enabledTransports: ['ws', 'wss'],
});

我的推送器设置:

'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' => true,
                'host' => '127.0.0.1',
                'port' => 6004,
                'scheme' => 'https',
                'curl_options' => [
                    CURLOPT_SSL_VERIFYHOST => 0,
                    CURLOPT_SSL_VERIFYPEER => 0,
                ]
            ],
        ],

我的网络套接字设置:

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

    'ssl' => [
        /*
         * Path to local certificate file on filesystem. It must be a PEM encoded file which
         * contains your certificate and private key. It can optionally contain the
         * certificate chain of issuers. The private key also may be contained
         * in a separate file specified by local_pk.
         */
        'local_cert' => base_path().'/ssl/server.crt',

        /*
         * Path to local private key file on filesystem in case of separate files for
         * certificate (local_cert) and private key.
         */
        'local_pk' => base_path().'/ssl/server.pem',

        /*
         * Passphrase for your local_cert file.
         */
        'passphrase' => null,
        'verify_peer' => false,
    ],

不使用SSL的设置:

我的回声设置:

window.Echo = new Echo({
    broadcaster: 'pusher',
    key: process.env.MIX_PUSHER_APP_KEY,
    wsHost: window.location.hostname,
    wsPort: 6004,
    disableStats: true,
    enabledTransports: ['ws', 'wss'],
});

我的推送器设置:

'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' => 6004,
                'scheme' => 'http',
            ],
        ],

我的网络套接字设置:

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

    'ssl' => [
        /*
         * Path to local certificate file on filesystem. It must be a PEM encoded file which
         * contains your certificate and private key. It can optionally contain the
         * certificate chain of issuers. The private key also may be contained
         * in a separate file specified by local_pk.
         */
        'local_cert' => null,

        /*
         * Path to local private key file on filesystem in case of separate files for
         * certificate (local_cert) and private key.
         */
        'local_pk' => null,

        /*
         * Passphrase for your local_cert file.
         */
        'passphrase' => null,

    ],

5 个答案:

答案 0 :(得分:5)

因此,在与ssl战斗了几天之后,我必须与我分享有关该主题的知识。 根据文档进行安装后,websockets使用了http,但使用ssl(443)之后则无法使用。 我认为我对.pem的正确设置和路径存在问题(让我们加密)(我尝试了一切,这项工作对我而言)。我在VPS服务器上使用端口*:443对Apatche2 mydomain.conf使用常规设置。 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' => true,
            'enable_statistics' => true,
            'encrypted' => true,
        ],
    ],
  'ssl' => [ 
        'local_cert' => '/etc/letsencrypt/live/server1.mydomain.com/fullchain.pem',
        'local_pk' => '/etc/letsencrypt/live/server1.mydomain.com/privkey.pem', 
        'passphrase' => null,
        'verify_peer' => false,
    ],
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' => true,
                'host' => 'server1.mydomain.com',
                'port' => 6001,
                'scheme' => 'https',
                'curl_options' => [
                    CURLOPT_SSL_VERIFYHOST => 0,
                    CURLOPT_SSL_VERIFYPEER => 0,
                ]
            ],
        ],  

Bootstrap.js:
  window.Echo = new Echo({
        auth:{ headers: { 'Authorization': 'Bearer ' + user.token } },
        broadcaster: 'pusher',
        key: process.env.MIX_PUSHER_APP_KEY,
        cluster: process.env.MIX_PUSHER_APP_CLUSTER,
        wsHost: window.location.hostname,
        wsPort: 6001,
        wssPort: 6001,
        disableStats: false, 
        enabledTransports: ['ws', 'wss']
 });

我希望这会有所帮助。 谢谢,祝你好运,很快再见:)

答案 1 :(得分:5)

在我的情况下,将pusher从6降级到

"pusher-js": "^4.3.1"

它开始工作。 Javascript我爱你! ?

答案 2 :(得分:1)

我也遇到了这个问题,并发布了一个更详细的问题,向我展示了防火墙 laravel nuxt nginx websockets 。几天后,找到了解决方案:Laravel + Nuxt + Nginx: WebSocket is closed before the connection is established

For comparison, see also the question itself on the link above.

项目设置

防火墙

netstat -ntlp | grep LISTEN

root@dsde1032-21892:~# netstat -ntlp | grep LISTEN
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      1066/nginx: master
tcp        0      0 0.0.0.0:6001            0.0.0.0:*               LISTEN      7768/php
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1064/sshd
tcp        0      0 127.0.0.1:3000          0.0.0.0:*               LISTEN      1173/node
tcp        0      0 0.0.0.0:443             0.0.0.0:*               LISTEN      1066/nginx: master
tcp        0      0 127.0.0.1:3306          0.0.0.0:*               LISTEN      1078/mysqld
tcp6       0      0 :::22                   :::*                    LISTEN      1064/sshd

lsof -i -P -n | grep LISTEN

root@dsde1032-21892:~# lsof -i -P -n | grep LISTEN
sshd     1064     root    3u  IPv4  20044      0t0  TCP *:22 (LISTEN)
sshd     1064     root    4u  IPv6  20138      0t0  TCP *:22 (LISTEN)
nginx    1066     root    6u  IPv4  20168      0t0  TCP *:443 (LISTEN)
nginx    1066     root    7u  IPv4  20169      0t0  TCP *:80 (LISTEN)
mysqld   1078    mysql   31u  IPv4  20463      0t0  TCP 127.0.0.1:3306 (LISTEN)
node     1173     root   18u  IPv4  20902      0t0  TCP 127.0.0.1:3000 (LISTEN)
nginx    7402 www-data    6u  IPv4  20168      0t0  TCP *:443 (LISTEN)
nginx    7402 www-data    7u  IPv4  20169      0t0  TCP *:80 (LISTEN)
php      7768     root    5u  IPv4 110549      0t0  TCP *:6001 (LISTEN)

ufw状态

root@dsde1032-21892:~# ufw status
Status: active

To                         Action      From
--                         ------      ----
OpenSSH                    ALLOW       Anywhere
Nginx Full                 ALLOW       Anywhere
6001                       ALLOW       Anywhere
OpenSSH (v6)               ALLOW       Anywhere (v6)
Nginx Full (v6)            ALLOW       Anywhere (v6)
6001 (v6)                  ALLOW       Anywhere (v6)

ufw显示收听内容

root@dsde1032-21892:~# ufw show listening
tcp:
  22 * (sshd)
   [ 1] allow OpenSSH

  443 * (nginx)
   [ 2] allow 'Nginx Full'

  6001 * (php7.4)
   [ 3] allow 6001

  80 * (nginx)
   [ 2] allow 'Nginx Full'

tcp6:
  22 * (sshd)
   [ 4] allow OpenSSH

Laravel

vim /var/www/api/config/websockets.php

...
    'apps' => [
        [
            'id' => env('PUSHER_APP_ID'),
            'name' => env('APP_NAME'),
            'key' => env('PUSHER_APP_KEY'),
            'secret' => env('PUSHER_APP_SECRET'),
            'path' => env('PUSHER_APP_PATH'),
            'capacity' => null,
            'enable_client_messages' => true,
            'enable_statistics' => false,
        ],
    ],
...
    'ssl' => [
        'local_cert' => '/etc/letsencrypt/live/larastart.site/fullchain.pem',
        'local_pk' => '/etc/letsencrypt/live/larastart.site/privkey.pem',
        'passphrase' => null,
        'verify_peer' => false
    ],
...

vim /var/www/api/config/broadcasting.php

...
    'connections' => [
        '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'),
                'useTLS' => true,
                'encrypted' => false,
                'host' => '127.0.0.1',
                'port' => 6001,
                'scheme' => 'https',
                'curl_options' => [
                        CURLOPT_SSL_VERIFYHOST => 0,
                        CURLOPT_SSL_VERIFYPEER => 0,
                ]

            ],
        ],
...
    ],
...

Nuxt

vim /var/www/client/package.json

{
  "name": "frontend",
  "version": "1.0.0",
  "private": true,
  "config": {
    "nuxt": {
      "port": "3000"
    }
  },
  "scripts": {
    "dev": "nuxt",
    "build": "nuxt build",
    "start": "nuxt start",
    "export": "nuxt export",
    "serve": "nuxt serve"
  },
  "dependencies": {
    "@nuxtjs/axios": "^5.12.2",
    "@nuxtjs/dotenv": "^1.4.1",
    "@nuxtjs/laravel-echo": "^1.1.0",
    "@nuxtjs/proxy": "^2.0.1",
    "nuxt": "^2.13.0",
    "pusher-js": "^4.4.0"
  },
  "devDependencies": {}
}

vim /var/www/client/plugins/echo.js

import Echo from 'laravel-echo';

export default (app) => {
    window.Pusher = require('pusher-js');

    window.Echo = new Echo({
        broadcaster: process.env.BROADCAST_DRIVER,
        key: process.env.PUSHER_APP_KEY,
        cluster: process.env.PUSHER_APP_CLUSTER,

        forceTLS: true,
        encrypted: false,
        wsHost: window.location.hostname,
        wsPort: 6001,
        wssPort: 6001,
        disableStats: true,
        enabledTransports: ['ws', 'wss']
    });
}

Nginx

vim /etc/nginx/nginx.conf

user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;

events {
        worker_connections 768;
        # multi_accept on;
}

http {

        ##
        # Basic Settings
        ##

        sendfile on;
        tcp_nopush on;
        types_hash_max_size 2048;
        # server_tokens off;

        # server_names_hash_bucket_size 64;
        # server_name_in_redirect off;

        include /etc/nginx/mime.types;
        default_type application/octet-stream;

        ##
        # SSL Settings
        ##

        ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
        ssl_prefer_server_ciphers on;

        ##
        # Logging Settings
        ##

        access_log /var/log/nginx/access.log;
        error_log /var/log/nginx/error.log;

        ##
        # Gzip Settings
        ##

        gzip on;

        # gzip_vary on;
        # gzip_proxied any;
        # gzip_comp_level 6;
        # gzip_buffers 16 8k;
        # gzip_http_version 1.1;
        # gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

        ##
        # Virtual Host Configs
        ##

        include /etc/nginx/conf.d/*.conf;
        include /etc/nginx/sites-enabled/*;
}


#mail {
#       # See sample authentication script at:
#       # http://wiki.nginx.org/ImapAuthenticateWithApachePhpScript
#
#       # auth_http localhost/auth.php;
#       # pop3_capabilities "TOP" "USER";
#       # imap_capabilities "IMAP4rev1" "UIDPLUS";
#
#       server {
#               listen     localhost:110;
#               protocol   pop3;
#               proxy      on;
#       }
#
#       server {
#               listen     localhost:143;
#               protocol   imap;
#               proxy      on;
#       }
#}

vim /etc/nginx/sites-available/larastart.site

server {
        server_name     larastart.site;
        root            /var/www/api/public;

        add_header X-Frame-Options              "SAMEORIGIN";
        add_header X-XSS-Protection             "1; mode=block";
        add_header X-Content-Type-Options       "nosniff";

        # Priority file extensions
        index index.php index.html index.htm index.nginx-debian.html;

        charset utf-8;

        # Check for the existence of files matching a provided url, forward to 404 if not found
        location /api {
                try_files $uri $uri/ /index.php?$query_string;
        }

        # Serve static files directly
        location ~* ^/storage/(.*)\.(jpg|jpeg|gif|bmp|png|ico)$ {
                access_log off;
        }

        location / {
                proxy_pass                          http://127.0.0.1:3000;
                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;
                proxy_set_header X-VerifiedViaNginx yes;
                proxy_read_timeout                  300;
                proxy_connect_timeout               300;
        }

        location /app {
                proxy_pass             https://larastart.site: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;
        }

        error_page 404 /index.php;

        # pass PHP scripts to FastCGI server
        location ~ \.php$ {
                fastcgi_pass  unix:/var/run/php/php7.4-fpm.sock;
                fastcgi_index index.php;
                fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
                include fastcgi_params;
        }

        # deny access to .htaccess files, if Apache's document root concurs with nginx's one
        location ~ /\.(?!well-known).* {
               deny all;
        }

        listen 443 ssl; # managed by Certbot

        ssl_certificate     /etc/letsencrypt/live/larastart.site/fullchain.pem;     # managed by Certbot
        ssl_certificate_key /etc/letsencrypt/live/larastart.site/privkey.pem;       # managed by Certbot
        include             /etc/letsencrypt/options-ssl-nginx.conf;                # managed by Certbot
        ssl_dhparam         /etc/letsencrypt/ssl-dhparams.pem;                      # managed by Certbot
}

server {
        if ($host = larastart.site) {
                return 301 https://$host$request_uri;
        } # managed by Certbot

        listen 80;
        server_name larastart.site;
        return 404; # managed by Certbot
}

答案 3 :(得分:0)

您是否尝试过在“ window.Echo”中使用这些选项?

 host:          window.location.hostname,
 httpHost:      window.location.hostname,

答案 4 :(得分:0)

通过在websockets.php中添加ssl路径来解决此问题。我正在使用我在Plesk中添加的购买的SSL。在cli中,证书的路径是从根目录开始的:cd / usr / local / psa / var / certificates,然后我做了'ls'检查证书名称。在我的情况下,我将证书与私钥一起使用,并作为local_cert路径和local_pk路径添加到config / websockets.php

中。

最终设置:

websockets.php

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

 'ssl' => [
        /*
         * Path to local certificate file on filesystem. It must be a PEM encoded file which
         * contains your certificate and private key. It can optionally contain the
         * certificate chain of issuers. The private key also may be contained
         * in a separate file specified by local_pk.
         */
        'local_cert' => env('ssl_certificate', null),

        /*
         * Path to local private key file on filesystem in case of separate files for
         * certificate (local_cert) and private key.
         */
        'local_pk' => env('ssl_certificate_key', null),

        /*
         * Passphrase for your local_cert file.
         */
        'passphrase' => null,
        'verify_peer' => false,
    ],

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'),
                'useTLS' => true,
                'host' => '127.0.0.1',
                'port' => 6004,
                'scheme' => 'https',
                 'curl_options' => [
                    CURLOPT_SSL_VERIFYHOST => 0,
                    CURLOPT_SSL_VERIFYPEER => 0,
                ]
            ],
        ],

bootstrap.js

import Echo from 'laravel-echo'

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

window.Echo = new Echo({
    broadcaster: 'pusher',
    key: process.env.MIX_PUSHER_APP_KEY,
    wsHost: window.location.hostname,
    wsPort: 6004,
    wssPort: 6004,
    disableStats: true,
    cluster: process.env.MIX_PUSHER_APP_CLUSTER,
    encrypted: true
});

顺便说一句,当您在bootstrap.js中进行更改时,请不要忘记运行npm run dev 我正在端口6004上运行它,所以如果您在6001上运行它,别忘了更改我在上面的设置