Ratchet WebSocket Server可以向客户端发送消息吗?

时间:2012-10-13 15:42:38

标签: php sockets websocket ratchet

我想使用棘轮(http://socketo.me)来实现iPhone Apps和Server之间的永久连接。我需要在应用程序和服务器之间交换数据。

从这个示例(http://socketo.me/docs/hello-world)我发现我有一个函数 onMessage ,当应用程序发送按摩到服务器并且服务器可以发送一个对应用程序的响应。

但是服务器还必须能够在不从应用程序获取数据的情况下将数据发送到应用程序。例如,已建立应用程序和服务器之间的连接。服务器上发生了一些事情,我们需要向应用程序发送新数据。我怎么能这样做,是否可能?

主要问题是如何从服务器向应用程序发送数据?

感谢您的帮助。

3 个答案:

答案 0 :(得分:13)

这确实是可能的。您需要以某种方式与WebSocket服务器进程通信。您可以通过使用某种形式的消息传递来做到这一点,无论是RPC还是消息队列。

Ratchet本身基于React事件循环。这意味着与Ratchet的任何形式的通信都必须与该事件循环集成。 On the React homepage您可以看到一些已经存在的集成:

在Ratchet文档中有a tutorial on how to use React/ZMQ,以便将消息从任何地方推送到您的WebSocket服务器。

答案 1 :(得分:6)

Ratchet还实现了WAMP,其中包括PubSub。因此,您的客户可以订阅某些主题,您可以让其他客户端(在您的后端基础架构上运行)发布到这些主题。你可以让一个基于AutobahnPython的客户端通过Ratchet发布到基于AutobahnAndroid的移动应用程序或基于AutobahnJS的HTML5客户端。

答案 2 :(得分:0)

我有完全相同的问题,这就是我所做的。

基于hello world tutorial,我用一个数组替换了SplObjectStorage。在介绍我的修改之前,我想评论一下,如果你完成了这个教程并理解了它,那么唯一阻止你自己解决这个问题的方法可能就是不知道SplObjectStorage是什么。

class Chat implements MessageComponentInterface {
    protected $clients;

    public function __construct() {
        $this->clients = array();
    }

    public function onOpen(ConnectionInterface $conn) {
        // Store the new connection to send messages to later
        $this->clients[$conn->resourceId] = $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 $key => $client) {
            if ($from !== $client) {
                // The sender is not the receiver, send to each client connected
                $client->send($msg);
            }
        }
        // Send a message to a known resourceId (in this example the sender)
        $client = $this->clients[$from->resourceId];
        $client->send("Message successfully sent to $numRecv users.");
    }

    public function onClose(ConnectionInterface $conn) {
        // The connection is closed, remove it, as we can no longer send it messages
        unset($this->clients[$conn->resourceId]);

        echo "Connection {$conn->resourceId} has disconnected\n";
    }

    public function onError(ConnectionInterface $conn, \Exception $e) {
        echo "An error has occurred: {$e->getMessage()}\n";

        $conn->close();
    }
}

当然,要使其真正有用,您可能还需要添加数据库连接,并存储/检索这些resourceIds。