1

我有 laravel-websockets 为 laravel 应用程序制作的套接字服务器,通过正常ws我可以使用 laravel-echo 在网页和外部 node.js 脚本中建立连接,一切都很好。问题来自于 ssl。该站点正在使用 apache,并且在 laravel-websockets 文档中缺少这种 ssl 集成,但找到了一些为 apache 制作反向代理的解决方案。反向代理仍然适用于正常连接,但不适用于外部 node.js 脚本 - 保持控制台日志记录unavailable

我的配置有问题还是需要做其他事情。

  • 反向代理的虚拟主机子域配置
<IfModule mod_ssl.c>
<VirtualHost *:443>
    ServerAdmin admin@admin.com
    ServerName socket.my-domain.com
    ServerAlias www.socket.my-domain.com

    SSLEngine on
    SSLProxyEngine on
    SSLProxyVerify none
    SSLProxyCheckPeerCN off
    SSLProxyCheckPeerName off
    SSLProxyCheckPeerExpire off

SSLCertificateFile /etc/letsencrypt/live/socket.my-domain.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/socket.my-domain.com/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf

  <Proxy *>
    Order deny,allow
    Allow from all
  </Proxy>

  <Location />
    RewriteEngine on
    RewriteCond %{HTTP:UPGRADE} ^WebSocket$ [NC]
    RewriteCond %{HTTP:CONNECTION} Upgrade$ [NC]
    RewriteRule .* ws://127.0.0.1:40126%{REQUEST_URI} [P,L]

    ProxyPass http://127.0.0.1:40126/
    ProxyPassReverse http://127.0.0.1:40126/
  </Location>


</VirtualHost>
</IfModule>

  • 广播.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' => false,
                    'encrypted' => true,
                    'host' => env('WEBSOCKET_HOST'),
                    'port' => env('LARAVEL_WEBSOCKETS_PORT'),
                    'scheme' => 'http',
                    'curl_options' => [
                        CURLOPT_SSL_VERIFYHOST => 0,
                        CURLOPT_SSL_VERIFYPEER => 0,
                    ],
                ],
            ]
  • websockets.php
        [
            '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('LARAVEL_WEBSOCKETS_SSL_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' => env('LARAVEL_WEBSOCKETS_SSL_LOCAL_PK', null),

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

  • .env
BROADCAST_DRIVER=pusher
PUSHER_APP_ID=123456
PUSHER_APP_SECRET=ituc16ngcf
PUSHER_APP_KEY=zns8tgs6r91
PUSHER_APP_CLUSTER=mt1
WEBSOCKET_HOST=127.0.0.1
LARAVEL_WEBSOCKETS_PORT=40126
WEBSOCKETS_URL=socket.my-domain.com
  • 外部 node.js 脚本
global.Pusher = require('pusher-js');
global.Echo = require('laravel-echo');

global.broadcast_auth_path = 'some_auth_link';
global.token = "some authorized token";
global.broadcast_auth_headers = {
    headers: {
        Authorization: "Bearer " + token
    }
};

var echoConfig = {
    broadcaster: 'pusher',
    key: 'zns8tgs6r91',
    cluster: 'mt1',
    wsHost: 'socket.my-domain.com',
    wsPort: 80,
    wssPort = 443,
    authEndpoint: broadcast_auth_path,
    auth: { ... broadcast_auth_headers },
    forceTLS: true,
    encrypted: true,
    disableStats: true,
    enabledTransports: [ 'wss', 'ws'],
}
Pusher.logToConsole = true;

Echo = new Echo(echoConfig);

Echo.connector.pusher.connection.bind( 'error', function( err ) {
    console.log(err);
});

Echo.connector.pusher.connection.bind('connected', function( ) {
    console.log('connected');
});

Echo.connector.pusher.connection.bind('disconnected', function( ) {
    console.log('disconnected');
});

Echo.connector.pusher.connection.bind('connecting', function( ) {
    console.log('connecting');
});
Echo.connector.pusher.connection.bind('initialized', function( ) {
    console.log('initialized');
});
Echo.connector.pusher.connection.bind('unavailable', function() {
    console.log('unavailable');
});
Echo.connector.pusher.connection.bind('failed', function( ) {
    console.log('failed');
});
  • 套接字服务器启动命令 php artisan websockets:serve --host=127.0.0.1 --port=40126
4

1 回答 1

0

问题是 pusher-js(对于 nodejs)websockets 集成对来自 dns 的指向 ip 地址产生了问题,这导致 ssl altnames 仅按字母顺序指向第一个子域(在我的情况下这是错误的)。

简单的解决方案是在第一个 alhabetically 之前创建新的子域反向代理(aawss 前面有双 aa)并且一切运行顺利。

于 2020-10-23T14:30:09.287 回答