带有apache代理的Socket.io

时间:2015-12-23 16:05:27

标签: node.js apache socket.io

我试图用apache设置proxyng,以便能够在我的nodejs应用程序中使用socket.io。但我在客户端收到此错误消息:

WebSocket connection to 'wss://example.com/tools/socket.io/?EIO=3&transport=websocket&sid=eOGwJSC14TTWhHRMAAAR' failed: Error during WebSocket handshake: Unexpected response code: 400

继承我的apache配置:

     <VirtualHost *:443>
            ServerName example.com
            ServerAlias example.com
            #SSLRequireSSL
            SSLProtocol all -SSLv2  -SSLv3
            SSLCompression off
            SSLHonorCipherOrder on
            SSLEngine on
            SSLCertificateFile /etc/ssl/main.pem
            SSLCertificateKeyFile /etc/ssl/dec_ssl.key
            SSLCertificateChainFile /etc/ssl/sub.class1.server.ca.pem
            SSLCACertificateFile /etc/ssl/main.pem
            SSLProxyEngine On

            ProxyPreserveHost On
            ProxyRequests off
    </VirtualHost>

    <Location /tools/>
            ProxyPass http://localhost:8181/
            ProxyPassReverse http://localhost:8181/
    </Location>

这是客户端代码:

socket = io.connect("https://example.com",{path:'/tools/socket.io'});
socket.on("connect", function () {
    console.log("socketio Connected to server!");
});

我需要在apache配置中添加什么来摆脱这个错误?

编辑:我的apache版本:服务器版本:Apache / 2.4.6(CentOS)

2 个答案:

答案 0 :(得分:5)

我已成功使用Apache 2.4.16,旧版本可能无法正常使用。

<VirtualHost *:443>
        ServerName example.com
        ServerAlias example.com
        #SSLRequireSSL
        SSLProtocol all -SSLv2  -SSLv3
        SSLCompression off
        SSLHonorCipherOrder on
        SSLEngine on
        SSLCertificateFile /etc/ssl/main.pem
        SSLCertificateKeyFile /etc/ssl/dec_ssl.key
        SSLCertificateChainFile /etc/ssl/sub.class1.server.ca.pem
        SSLCACertificateFile /etc/ssl/main.pem
        SSLProxyEngine On

        ProxyPreserveHost On
        ProxyRequests off
</VirtualHost>

<Location /tools/>
        RewriteEngine On
        RewriteCond %{REQUEST_URI}  ^/tools/socket.io            [NC]
        RewriteCond %{QUERY_STRING} transport=websocket    [NC]
        RewriteRule "^/tools/socket.io"           "ws://localhost:8181/socket.io/" [P,L]

        ProxyPass http://localhost:8181/
        ProxyPassReverse http://localhost:8181/
</Location>

ProxyPass不会处理websocket升级。因此,您要做的是将这些请求重定向到ws://

我认为一般情况下你不应该使用Location来处理这个问题,但是这个配置应该适合你。

答案 1 :(得分:1)

我根据@Gary

添加了以下内容
    <Location /tools/>

    RewriteEngine On
    RewriteCond %{REQUEST_URI}  ^/tools/socket.io            [NC]
    RewriteCond %{QUERY_STRING} transport=websocket    [NC]
    RewriteRule "/(.*)"        "ws://localhost:8181/socket.io/" [P,L]

    ProxyPass http://localhost:8181/
    ProxyPassReverse http://localhost:8181/
   </Location>

使用路径属性从客户端连接套接字。

 discussionSocket = io("https://localhost.in", {
  path:'/tools/socket.io',
  secure: true,
  reconnection: true,
  reconnectionDelay: 1000,
  reconnectionDelayMax: 5000,
  reconnectionAttempts: 99999
});

但为此,我们必须从套接字服务器创建代码中删除ssl配置: -

var http = require('http').Server(app);