带有棘轮的 PHP WebSockets - 示例不起作用

Posted

技术标签:

【中文标题】带有棘轮的 PHP WebSockets - 示例不起作用【英文标题】:PHP WebSockets with Ratchet - example doesn't work 【发布时间】:2013-12-24 16:38:28 【问题描述】:

这里先介绍一些背景。

    我的目标是使用 Ratchet WebSockets 创建双向客户端-服务器通信。

    如here 所述,我已安装棘轮和配套软件。

    我已成功创建了一个 Hello World 应用程序,如 here 所述。

    现在我正在尝试使用 this 教程创建推送功能。我已经复制了代码,稍作修改(在下面的代码 cmets 中注明了修改),安装了 ZMQ 库(最新版本,将其添加到 php.ini,显示在 php -m - 简而言之,它已正确安装)。但是 WebSocket 不起作用。

我将在下面提供我的测试过程以及指向我的域的实时链接,以便您自己检查。

    我的推送服务器和他们教程里的一模一样,只是IP改成了我服务器的IP。我通过 SSH 运行它,它似乎连接正确。

    我的 Pusher 类位于 MyApp 命名空间中,与教程中的代码和相对位置相同。

    我的 post.php 稍作修改,因为无需费心处理 mysql 查询:

$entryData = array(        //hard-coded content of $entryData for simplicity
    'cat'     => "macka"
  , 'title'   => "naslov"
  , 'article' => "tekst"
  , 'when'    => time()
);

// This is our new stuff
$context = new ZMQContext();
$socket = $context->getSocket(ZMQ::SOCKET_PUSH, 'my pusher');
$socket->connect("tcp://light-speed-games.com:5555");       //my domain, still using port 5555 as in their example

$socket->send(json_encode($entryData));

此文件位于here。

    我的 client.php 和他们的一样,除了我必须为 IE 添加一个小修复程序才能使用when.js。我的问题与浏览器无关,与添加修复程序之前的问题相同。
<script>
    window.define = function(factory)     //my addition
        try delete window.define;  catch(e) window.define = void 0;  // IE
        window.when = factory();
    ;
    window.define.amd = ;
</script>
<script src="/apps/scripts/when.js"></script> 
<script src="http://autobahn.s3.amazonaws.com/js/autobahn.min.js"></script>
<script>
    var conn = new ab.Session(
        'ws://light-speed-games.com:8080' // The host (our Ratchet WebSocket server) to connect to
      , function()             // Once the connection has been established
            conn.subscribe('kittensCategory', function(topic, data) 
                // This is where you would add the new article to the DOM (beyond the scope of this tutorial)
                console.log('New article published to category "' + topic + '" : ' + data.title);
            );
        
      , function()             // When the connection is closed
            console.warn('WebSocket connection closed');
        
      ,                        // Additional parameters, we're ignoring the WAMP sub-protocol for older browsers
            'skipSubprotocolCheck': true
        
    );
</script>

此文件位于here。

理论上,应该发生的事情是这样的(例如):我在​​ Chrome 中打开 client.php 并打开控制台;然后我在 Firefox 中打开 post.php; Chrome 的控制台应显示消息“已发布新文章...”等(来自client.php 中的conn.subscribe 函数)。但是,当我这样做时,什么也没有发生。连接保持打开状态(在我通过 SSH 关闭 push-server.php 之前,不会显示“连接关闭”错误)。控制台仍然是空的。

我认为这是过去几天的所有相关信息,其中很大一部分我都花在了试图弄清楚这一点上。但是,我什至无法确定问题出在代码上还是与我可能不知道的某些服务器配置设置有关。所以,我来找你,希望有人能指出我正确的方向。

重要修改

我很确定问题在于 Autobahn.js 方法 conn.subscribe 无法正常工作。正在建立连接。当我将代码更改为:

function()             // Once the connection has been established
            console.log('Connection established');
            conn.subscribe('kittensCategory', function(topic, data) 
                // This is where you would add the new article to the DOM (beyond the scope of this tutorial)
                console.log('New article published to category "' + topic + '" : ' + data.title);
            );
        

然后Connection established 正确显示在控制台中。所以我相信我们需要对订阅方法进行故障排除。如果有人可以向我解释它是如何工作的,以及“主题”和“数据”到底应该是什么,那将有很大帮助。 Autobahn 文档使用 URL 作为此方法的参数(请参阅 here)。

【问题讨论】:

我想知道如果解决方案是端口未打开,是否应该将其关闭为不可重现。 【参考方案1】:

您的客户正在寻找kittensCategory 中的文章,但您发送的是macka 类别。试试这个:

$entryData = array(
    'cat'     => "kittensCategory",
    'title'   => "naslov",
    'article' => "tekst",
    'when'    => time()
);

【讨论】:

谢谢,我早上试试(现在不在家)。这对我来说有点奇怪,我想我不明白。我认为“kittensCategory”只是一个数组项,其中“cat”是键,“kittensCategory”是值。然后它引用data.title - 会按预期打印我们的“naslov”吗? 把“macka”改成“kittensCategory”还是不行。你能向我解释一下整个conn.subscribe 函数吗?我不明白。在这种情况下,topicdata 是什么? 另外,我已经用一些新信息编辑了我的问题,部分基于您指出的内容,部分基于我刚刚所做的一些研究。【参考方案2】:

在端口 8080 上看到您的主机 light-speed-games.com 无法正常运行是否正确?如果没有,我建议解决此问题,因为它可能会导致您的问题。

【讨论】:

抱歉回复晚了,不知何故错过了你的回答。你是说我应该向我的托管服务提供商咨询这个端口是否工作不正常? 从您的计算机执行 telnet 以在端口 8080 上托管 light-speed-games.com。您可能会看到与我相同的结果(连接不会建立)。我不知道原因,也不知道你应该联系你的托管公司来解决这个问题(尽管我想你应该:))。因为连接不会在这个“低级”测试中建立,我明白为什么你的 javascript 也没有执行它的逻辑 -> 它没有连接。 这是有道理的——我会在今天晚些时候试试这个并告诉你。很抱歉,由于我要过新年,所以赏金已过期,但如果可行,我至少可以奖励一半的赏金。 你是对的,该端口对 TCP 连接关闭。我尝试用iptables -I INPUT -p tcp --dport 8080 --syn -j ACCEPT 打开它,然后用service iptables save 重新启动Apache,但它似乎仍然关闭。有什么想法吗? 顺便说一句,我对端口 5555 也有同样的看法。不过,像 21 和 22 这样的标准端口运行良好。

以上是关于带有棘轮的 PHP WebSockets - 示例不起作用的主要内容,如果未能解决你的问题,请参考以下文章

使用棘轮 php 将消息推送到 websockets 而没有 ZeroMQ

棘轮和 Websockets - 无法正常工作

在 laravel 中使用 Supervisor 运行棘轮 websockets 和队列

棘轮:是不是应该通过“php”命令手动将其作为服务器运行?

如何使用棘轮 websockets 将数据发送到服务器 onload?

PHP棘轮和WebRTC