带棘轮的Websockets立即关闭



使用插座上的指示。我的网站,我试图使websockets工作使用棘轮php。根据说明,我需要Ratchet 0.2版本。*在我的作曲家。json文件。我使用php 5.4.9-4ubuntu2和Apache 2。对于浏览器,我使用Firefox 21.0和Chrome 26.0.1410.63。这个网站说Rachet支持Firefox 6-20和Chrome 13-26,但是使用Firefox 21和Chrome 26的结果几乎是一样的。

这是我实现MessageComponentInterface的类。

<?php
namespace WebsocketTest;
use RatchetMessageComponentInterface;
use RatchetConnectionInterface;
require dirname (__DIR__).'/../../../../vendor/autoload.php';
class Chat implements MessageComponentInterface
{
    protected $clients;
    public function __construct ()
    {
        $this->clients = new SplObjectStorage;
    }
    public function onOpen (ConnectionInterface $conn)
    {
        // Store the new connection to send messages to later
        $this->clients->attach ($conn);
        echo "New connection! ({$conn->resourceId})n";
    }
    public function onMessage (ConnectionInterface $from, $msg)
    {
        $numRecv = count ($this->clients) - 1;
        echo sprintf ('Connection %d sending message "%s" to %d other connection%s'."n", $from->resourceId, $msg, $numRecv, $numRecv == 1 ? '' : 's');
        foreach ($this->clients as $client)
        {
            if ($from !== $client)
            {
                // The sender is not the receiver, send to each client connected
                $client->send ($msg);
            }
        }
    }
    public function onClose (ConnectionInterface $conn)
    {
        // The connection is closed, remove it, as we can no longer send it messages
        $this->clients->detach ($conn);
        echo "Connection {$conn->resourceId} has disconnectedn";
    }
    public function onError (ConnectionInterface $conn, Exception $e)
    {
        echo "An error has occurred: {$e->getMessage()}n";
        $conn->close ();
    }
}

下面是我的shell脚本代码

<?php
use RatchetServerIoServer;
use WebsocketTestChat as Chat;
require_once __DIR__.'/Chat.php';
$server = IoServer::factory (new Chat (), 8080);
$server->run ();
下面是我从shell脚本中得到的输出。
New connection! (38)
Connection 38 sending message "GET / HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Host: www.zf2.dev:8080
Origin: http://www.zf2.dev
Pragma: no-cache
Cache-Control: no-cache
Sec-WebSocket-Key: YHbsxEgVhWTDJjaBJAGHdQ==
Sec-WebSocket-Version: 13
Sec-WebSocket-Extensions: x-webkit-deflate-frame
" to 1 other connection
New connection! (39)
Connection 39 sending message "GET / HTTP/1.1
Host: www.zf2.dev:8080
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:21.0) Gecko/20100101 Firefox/21.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Sec-WebSocket-Version: 13
Origin: http://www.zf2.dev
Sec-WebSocket-Key: EPpLFS3bXx/eC+WaoNDacA==
Connection: keep-alive, Upgrade
Pragma: no-cache
Cache-Control: no-cache
Upgrade: websocket
" to 2 other connections
Connection 37 has disconnected
Connection 38 has disconnected

这是我的javascript代码。创建连接后,将其输出到javascript控制台。

var conn = null;
function test_websockets ()
{
    conn = new WebSocket ('ws://www.zf2.dev:8080');
    console.log (conn);
    conn.onopen = function (e) { console.log ("Connection established!"); };
    conn.onmessage = function (e) { console.log (e.data); };
    conn.onclose = function (e) { console.log ('closed') };
//  conn.send ('sending message from the client');
}
function test_ws_message ()
{
    conn.send ('the test message');
}

这是我在Chrome的javascript控制台得到的输出。

WebSocket {binaryType: "blob", extensions: "", protocol: "", onclose: null, onerror: null…}
 html5test.js:34
Uncaught Error: InvalidStateError: DOM Exception 11 html5test.js:47
test_ws_message html5test.js:47
onclick

这是我在Firefox中从Firebug得到的输出。

WebSocket { url="ws://www.zf2.dev:8080", readyState=0, bufferedAmount=0, more...}
html5test.js (line 34)
InvalidStateError: An attempt was made to use an object that is not, or is no longer, usable
[Break On This Error]   
conn.send ('the test message');
html5test.js (line 47)
closed
html5test.js (line 38)
Firefox can't establish a connection to the server at ws://www.zf2.dev:8080/.

conn = new WebSocket ('ws://www.zf2.dev:8080');

请注意,Firefox显示连接立即关闭,而Chrome没有。然而,Chrome从来没有显示连接打开,所以我不认为它是在任何浏览器上工作。看起来服务器脚本认为连接已经建立,但是两个浏览器都没有显示"连接建立!"消息,这表明调用了onopen方法。我能找到一条评论,暗示不兼容的websockets"握手"版本可能会导致这种情况发生,但我从来没有找到任何关于其他版本的Ratchet的信息,或者我需要做些什么才能在客户端和服务器上运行兼容的版本。我还发现一些评论说有时onopen根本不会被调用,这让我很难相信。任何关于问题可能是什么或如何解决它的想法将不胜感激。

如果你正确地遵循Ratchet的文档和RFC6455,那么你会注意到,当一个websocket连接请求被发出时,一个特定的响应被发送到客户端。除非收到响应,否则客户端将假定尚未建立连接。

您的情况下的问题是,正在处理连接的MessageComponentInterface在连接上没有响应任何套接字响应。然而,棘轮绑定了一个已经实现的名为WsServer的类,可以将Chat类的对象传递给它,并实现所需的操作。然而WsServer不是一个MessageComponentInterface,但是如果你把它包装在HttpServer里面,幸运的是它也捆绑了棘轮,你的问题就解决了。

所以你的新代码看起来像:

$server = IoServer::factory (new HttpServer(new WsServer(new Chat ())), 8080);

当然你需要在命名空间中添加WsServer和HttpServer

use

$server = IoServer::factory (new HttpServer(new WsServer(new Chat())), 8080);

代替

$server = IoServer::factory (new Chat (), 8080);

相关内容

  • 没有找到相关文章