WebSockets (Apache ProxyPass)

Posted

技术标签:

【中文标题】WebSockets (Apache ProxyPass)【英文标题】: 【发布时间】:2016-01-01 02:30:53 【问题描述】:

我希望通过 Apache 建立一个简单的 WebSocket 连接。

我正在运行两个 Web 服务器,一个是 Apache,另一个是 simple php WebSocket server 来处理套接字连接,它运行在托管在 RackSpace 上的 Ubuntu 盒子上。

我已经做了很多研究,但仍然没有找到一个很好的示例来显示在远程主机上以任何语言(在本例中为 PHP)设置 WebSocket 服务器的基本配置,我见过的每个示例一直在使用'localhost',在我看来这没什么用。


所以 Apache 的根目录是 /var/www/html(默认)并且正在侦听端口 8080,因此例如下面的目的 (www.mydomain.com:8080) 是源代码index.html页面。

<html>
<head>
<script>
document.addEventListener("DOMContentLoaded", init);
function init()
    var socket = new WebSocket("ws://www.mydomain.com:8080/sockets");
    setInterval(timer.sockstate, 3000, socket);
    socket.addEventListener('open', sock.open);
    socket.addEventListener('message', sock.msg);
    socket.addEventListener('error', sock.err);
    socket.addEventListener('close', sock.close);
 
var timer = 
    "sockstate": function(o)
        switch(o.readyState)
            case 0:
                console.log('CONNECTING...');
                break;
            case 1:
                console.log('OPEN...');
                break;
            case 2:
                console.log('CLOSING...');
                break;
            case 3:
                console.log('CLOSED...');
                break;
        
    
;
var sock = 
    "open": function(e)
        console.log(e);
    ,
    "msg": function(e)
        console.log(e);
    ,
    "err": function(e)
        console.log(e);
    ,
    "close": function(e)
        console.log(e);
    
;
</script>
</head>
<body></body>
</html>

现在 PHP 服务器正在 9000 端口上监听 127.0.0.1,这里是 source code,它可以通过 cmd 行 php -q /var/www/html/sockets/server.php 正常启动


最后是我在 Apache 中的配置文件

<VirtualHost *:8080>
    ServerName www.mydomain.com
    DocumentRoot /var/www/html  

    ProxyPass "/sockets/" "http://127.0.0.1:9000/"
    ProxyPassReverse "/sockets/" "http://127.0.0.1:9000/"
</VirtualHost>

我很肯定这不是网络问题,我 ufw status 确保两个端口 (8080/9000) 都被允许,并确保正在加载 mod_proxy 和 mod_proxy_wstunnel。

问题:那么我在 Apache Config 中做错了什么?

【问题讨论】:

【参考方案1】:

我刚刚在自己的服务器上完成了这个设置,所以我希望这对某人有所帮助。我的配置和你的很相似。这就是我要改变的

Javascript

//Notice the path ends with a trailing hash. Don't know whether it matters
var socket = new WebSocket('ws://www.domain.com:8080/socket/');

虚拟主机

# Protocol should be 'ws', not 'http', for mod_proxy_wstunnel to work
ProxyPass "/sockets/" "ws://127.0.0.1:9000/"
ProxyPassReverse "/sockets/" "ws://127.0.0.1:9000/"

因为 Apache 转发 WS 流量,所以 websocket 服务器不需要公开。您可以保持 9000 端口对互联网关闭。

我也启用了mod_proxy_http,但不知道是否需要。

如果没有发生重定向,请查看您的 Apache 错误日志。您已经提到了其中几件事,但请确保:

mod_proxymod_proxy_wstunnel 已加载 更改模块或 VirtualHost 配置后重新启动 Apache WS 服务器正在运行并侦听端口 9000 ProxyPass 位于正确的虚拟主机中

【讨论】:

以上是关于WebSockets (Apache ProxyPass)的主要内容,如果未能解决你的问题,请参考以下文章

WebSockets (Apache ProxyPass)

apache websockets反向代理

本地主机上的 Apache Tomcat websockets 实现

Websockets - 服务器端要求(Windows 服务器,不是 Apache)

如何使用 Apache 作为 WebSockets 的反向代理,以 Undertow 作为服务器

如何在生产中运行 Laravel Websockets(ubuntu + apache2)?