19

我想使用 Ratchet ( http://socketo.me ) 在 iPhone 应用程序和服务器之间建立永久连接。我需要在应用程序和服务器之间交换数据。

从这个例子(http://socketo.me/docs/hello-world)我发现我有一个函数 onMessage,当应用程序向服务器发送消息并且服务器可以发送响应时调用它应用程序。

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

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

感谢您的任何帮助。

4

3 回答 3

13

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

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

在 Ratchet 文档中,有一个关于如何使用 React/ZMQ将消息从任何地方推送到 WebSocket 服务器的教程。

于 2012-10-13T16:57:02.067 回答
7

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

于 2012-10-13T17:21:09.367 回答
0

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

Based on the hello world tutorial, I have substituted SplObjectStorage with an array. Before presenting my modifications, I'd like to comment that if you followed through that tutorial and understood it, the only thing that prevented you from arriving at this solution yourself is probably not knowing what SplObjectStorage is.

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();
    }
}

Of course to make it really useful you may also want to add in a DB connection, and store/retrieve those resourceIds.

于 2013-07-19T02:43:27.397 回答