【问题标题】:Socket.io with apache proxy带有 apache 代理的 Socket.io
【发布时间】:2018-04-26 15:03:21
【问题描述】:

我正在尝试使用 apache 设置代理,以便能够在我的 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)

【问题讨论】:

  • 你确定你的 socket.io 服务器正在监听 8181 吗?能直接打吗?
  • 你检查过你的 Apache 错误日志吗?
  • @M.Babcock,是的,服务器在 8181 上运行。我能够从 url 获取 socket.io.js:example.com/tools/socket.io/socket.io.js
  • 在不使用 apache 的情况下使用 nginx + nodejs 时收到确切的错误消息

标签: node.js apache socket.io


【解决方案1】:

我已经在 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 来处理这个问题,但是这个配置应该适合你。

【讨论】:

  • 你能指出我应该将这些行放在我的 apache 配置中的什么位置吗?如果我使用 /tools/ 而不是你的 / 会怎样?
  • 已更新您的配置。阅读 Location 上的 Apache 文档,这可能不是您配置的最佳方式,但在不了解更多信息的情况下,我无法确定。
  • 这对我没有任何改变。仍然遇到与原始帖子相同的错误。
  • 你运行的是什么版本的 Apache?
  • 我还在条件中添加了 /tools,查看最新更新。您可能需要打开重写日志记录,以便查看您看到的具体错误。
【解决方案2】:

我根据@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);

【讨论】:

  • 更新了我在其中的答案也删除了 websocket 的 400 错误
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-01
  • 2020-06-15
  • 1970-01-01
相关资源
最近更新 更多