问题描述
我有一个由laravel-websockets为laravel应用制作的套接字服务器,通过普通的ws
我可以使用laravel-echo在网页和外部node.js脚本中建立连接,一切都很好。问题来自ssl。该站点正在使用apache,并且在laravel-websockets中,documantation缺少这种ssl集成,但是找到了一些针对apache的反向代理的解决方案。反向代理仍然适用于正常连接,但不适用于外部node.js脚本-保持控制台日志unavailable
。
我的配置有问题或也需要做其他事情。
- 反向代理的虚拟主机子域conf
<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>
'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'),'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',/*
* Passphrase for your local_cert file.
*/
'passphrase' => env('LaraVEL_WEBSOCKETS_SSL_PAsspHRASE','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');
});
解决方法
问题是,pusher-js(用于nodejs)的websockets集成使来自dns的指向ip地址出现问题,这导致ssl altname仅按字母顺序指向第一个子域(在我的情况下是错误的)。
一种简单的解决方案是在第一个字母排序之前先创建一个新的子域反向代理(前面带有双aa的aawss),然后一切顺利进行。