无法使用 ssl 和 apache 连接到 websocket

Posted

技术标签:

【中文标题】无法使用 ssl 和 apache 连接到 websocket【英文标题】:Can't connect to websocket using ssl and apache 【发布时间】:2019-08-14 12:33:49 【问题描述】:

我正在使用 socket.io 将我的客户端连接到服务器套接字。当我使用 http 时一切正常,但是当我尝试使用 https 时,客户端无法连接。

我尝试使用 http require('https') 并使用证书创建服务器,但没有成功。

现在经过一些代码更改和测试,这就是我的代码:

服务器,index.js

var https = require('https');
var app = express();
var options = 
   key: fs.readFileSync('./server-key.pem'), 
   cert: fs.readFileSync('./server-crt.pem'), 
   ca: fs.readFileSync('./ca-crt.pem'), 
   requestCert: false,
   rejectUnauthorized: false
;


var server = https.createServer(options, app);¡
var io = require('socket.io')(server);

server.listen(3003, function() 
        console.log('server up and running at %s port', 3003);
);


io.on('connection', function(client)
        console.log("NUEVO CLIENTE");
        client.on('event', function(data));
        client.on('disconnect', function());
        client.on('setRoom', function(room) 
                        client.room = room;
                        client.join(room);
        );
        client.on('leaveRroom', function(room) 
                        client.leave(room);
    );

);

使用端口 3003 连接服务器总是成功。

客户

$scope.socket = io.connect('https://socket.softgym.com/',  transports: ['websocket'],rejectUnauthorized: false);
$scope.socket.on('connect_error', function (data) 
                console.log(data);
    );

    $scope.socket.on('message', function(message) 
        $scope.getAttendance();
        $scope.clientDetails(message.user[0]);
    )

浏览器日志:

socket.io-client:manager opening https://socket.softgym.com/ +0ms
VM74:6 engine.io-client:socket creating transport "websocket" +5s
VM74:6 engine.io-client:socket setting transport websocket +1ms
VM74:6 socket.io-client:manager connect attempt will timeout after 20000 +4ms
VM74:7 WebSocket connection to 'wss://socket.softgym.com/socket.io/?EIO=3&transport=websocket' failed: Error during WebSocket handshake: Unexpected response code: 500
r.doOpen @ VM74:7
r.open @ VM74:7
r.open @ VM74:6
r @ VM74:6
r @ VM74:6
r.open.r.connect @ VM74:6
(anonymous) @ VM74:6
VM74:6 engine.io-client:socket socket error "type":"TransportError","description":"isTrusted":true +502ms
VM74:6 socket.io-client:manager connect_error +501ms
VM74:6 socket.io-client:manager cleanup +0ms
access.js:51 Error: websocket error
    at r.onError (eval at <anonymous> (jquery.min.js:2), <anonymous>:7:8015)
    at WebSocket.ws.onerror (eval at <anonymous> (jquery.min.js:2), <anonymous>:7:23668)
VM74:6 socket.io-client:manager reconnect attempt error +1ms
VM74:6 socket.io-client:manager will wait 5000ms before reconnect attempt +1ms
VM74:6 engine.io-client:socket socket close with reason: "transport error" +4ms
VM74:6 socket.io-client:manager attempting reconnect +5s
VM74:6 socket.io-client:manager readyState closed +1ms

对于 SSL,我使用 AWS 的负载均衡器。

这是我的 apache 网站:

<VirtualHost *:80>
        ServerName socket.softgym.com
        ServerAlias www.socket.softgym.com
        ServerAdmin webmaster@localhost
        RewriteEngine On
        RewriteCond %REQUEST_URI ^/socket.io          [NC]
        RewriteCond %QUERY_STRING transport=websocket [NC]
        RewriteRule /(.*) wss://localhost:3003/%1        [P,L]

        ProxyPass /socket.io https://localhost:3003/socket.io
        ProxyPassReverse /socket.io https://localhost:3003/socket.io

</VirtualHost>

# vim: syntax=apache ts=4 sw=4 sts=4 sr noet

我希望客户端通过 https 成功连接到服务器。

【问题讨论】:

你是如何使用 apache 的? AWS负载均衡器是直接转发请求到Node.js APP的PORT 3003,还是不转发? @MarcosCasagrande 是的,我正在使用 apache。 AWS 负载均衡器仅侦听协议 http 和 https 而不是直接向 PORT 3003 请求(编辑帖子)。 所以 apache 正在侦听端口 80,然后您将代理传递到您的 Node.js 服务器?如果是,请显示您的 apache2 设置。 %1 应该是什么的反向引用?在条件下没有捕获。 Apache 错误日志说明了什么? 【参考方案1】:

您的代理服务器似乎不支持 WebScotets 升级。如果您使用的是 apache,则配置并不简单。您必须安装 mod_proxy_ws_tunnel 模块才能执行此操作。

关注link


Web 套接字升级是用户从 HTTP 协议升级到 WebSckets 协议的过程,方法是发送升级标头,然后进行三向握手。您可能会发现一些关于使用 websocket 配置 apache 的资源 here


另外,如果不需要 apache 服务器,您可以使用另一个代理服务器。安装 nginx,你的生活会变得更轻松。然后只需将此配置添加到您的 nginx 配置中即可。

location ~* \.io 
  .. your configuration

  proxy_pass http://localhost:3000;
  proxy_redirect off;

  proxy_http_version 1.1;
  proxy_set_header Upgrade $http_upgrade;
  proxy_set_header Connection "upgrade";

希望对您有所帮助。

【讨论】:

它可以工作,但是将 apache2 和 nginx 安装在同一台服务器上会出现问题,我卸载了 apache2 并且它可以正常工作。

以上是关于无法使用 ssl 和 apache 连接到 websocket的主要内容,如果未能解决你的问题,请参考以下文章

启用 SSL 的网站无法连接到本地 C# Web 套接字服务器

XAMPP apache 无法连接到监听端口

在 JBoss EAP 6.2 中无法通过 SSL 连接到 SOAP 服务

使用 PHP 通过 IMAP 连接到 Gmail - SSL 上下文失败

使用 HTTPS 连接到 Web 服务时 Android SSL 握手失败

.NET 客户端连接到 ssl Web API