带有 apache mod_proxy_wstunnel 的 Websocket 不起作用

Posted

技术标签:

【中文标题】带有 apache mod_proxy_wstunnel 的 Websocket 不起作用【英文标题】:Websocket with apache mod_proxy_wstunnel doesn't work 【发布时间】:2017-02-06 02:41:08 【问题描述】:

我已经做好了准备:Apache 2.4 + php7 + WebSocket 访问此链接以查看我的准备情况 详情:Cannot load modules/mod_proxy_wstunnel.so into server 但是当我运行一个简单的 WebSocket 演示时,我遇到了一些问题。我不知道如何解决它们。

Websocket 对我来说是一个新概念。我了解到 Apache 2.4 支持带有 mod_proxy_wstunnel.so 的 WebSockets。 我的步骤:

    编辑httpd.conf,加载mod_proxymod_proxy_wstunnel(当然两者都在apachedir/modules中)
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so
    添加代理(仍在 httpd 中)
ProxyPass /ws ws://10.180.0.123/
ProxyPassReverse /ws ws://10.180.0.123/
    创建 html 客户端和 PHP 服务器 (cd apachedir/htdocs)

client.html

<html>
<script>
    var socket = new WebSocket("ws://10.180.0.123/server.php");
    socket.onopen = function(e)
        console.log("open success");
    
    socket.onmessage = function(e)
        console.log("mes:"+e);
    
    //socket.close();
    socket.send("Hello World");
</script>
<html>

server.php

<?php
  echo "hello";
?>

4.启动apache

/usr/local/apache2/bin/apachectl start

我的问题:

    当我打开:10.180.0.123/client.html 时,出现以下错误:
Uncaught InvalidStateError: Failed to execute 'send' on 'WebSocket': Still in CONNECTING state.  
WebSocket connection to 'ws://10.180.0.123/server.php' failed: Error during WebSocket handshake: Unexpected response code: 200  

我想我应该在server.php 中写一些代码,然后运行它。我对吗?我应该写什么。我在谷歌上没有找到任何信息。

    当我打开:10.180.0.123/ws/client.html 时,我得到以下 Apache 错误日志
[Wed Sep 28 00:14:54.063989 2016] [proxy:warn] [pid 6646:tid 140326217934592] [client 10.230.0.93:57508] AH01144: No protocol handler was valid for the URL /ws/client.html. If you are using a DSO version of mod_proxy, make sure the proxy submodules are included in the configuration using LoadModule.

似乎代理模块没有加载,但请看我的截图:

【问题讨论】:

【参考方案1】:

返回“hello”的 PHP 脚本不是 WebSocket 服务器。

您需要运行一个实际的 WebSocket 服务器并将您的代理配置指向它。

查看Ratchet 以获得基于 PHP 的 WebSocket 服务器。

当您运行 WebSocket 服务器时,您需要设置您的 Apache 配置。

假设它在同一台机器上运行在 8080 端口上:

ProxyPass /ws ws://localhost:8080/
ProxyPassReverse /ws ws://localhost:8080/

在您的client.html 中,您应该将您的WebSocket 连接到ws://10.180.0.123/ws

【讨论】:

感谢您的回复。您能告诉我 mod_proxy_wstunnel 和 Ratchet 之间的关系吗?我可以基于 mod_proxy_wstunnel 构建我的 websocket 服务器吗?我还需要 Ratchet 吗? mod_proxy_wstunnel 只是 Apache 的一个模块,所以代理支持 WebSockets。如果您想从与 Web 服务器相同的端口提供 WebSocket 连接或支持 SSL 加密的 WebSocket 连接而不需要实际的 WebSocket 来支持它,您只需要一个反向代理。但是你肯定需要一个单独的服务器来提供像 Ratchet 这样的 WebSockets。 你的解释很清楚,非常感谢。 您对我的问题 2 有什么想法吗:[Wed Sep 28 00:14:54.063989 2016] [proxy:warn] [pid 6646:tid 140326217934592] [client 10.230.0.93:57508] AH01144 : 没有协议处理程序对 URL /ws/client.html 有效。如果您使用的是 DSO 版本的 mod_proxy,请确保代理子模块包含在使用 LoadModule 的配置中。

以上是关于带有 apache mod_proxy_wstunnel 的 Websocket 不起作用的主要内容,如果未能解决你的问题,请参考以下文章

带有虚拟主机的 404 和带有 Apache (httpd) 的子目录

HTTP2,apache2,带有 certbot

在 apache2.conf 中包含 .htaccess 并带有“AllowOverride None”会减慢 Apache?

带有 apacheds 的示例活动目录 ldif 文件

带有 Apache Phoenix 的列族

带有特殊字符的 Apache SetEnv