Может ли Ratchet WebSocket Server отправлять сообщение самому клиенту?
Я хочу использовать Ratchet (http://socketo.me) для постоянного соединения между приложениями iPhone и сервером. И мне нужно обмениваться данными между приложениями и сервером.
В этом примере (http://socketo.me/docs/hello-world) Я выяснил, что у меня есть функция onMessage, которая будет вызываться, когда приложение отправит массаж на сервер, и сервер может отправить ответ на приложение.
Но сервер также должен иметь возможность отправлять данные в приложение, не получая данные из приложения. Например, была установлена связь между приложением и сервером. Что-то случилось на сервере, и нам нужно отправить новые данные в приложение. Как я могу это сделать и возможно ли это?
Основной вопрос: как я могу отправить данные в приложение с сервера?
Спасибо за любую помощь.
Ответы
Ответ 1
Это действительно возможно. Вам нужно как-то связаться с процессом сервера WebSocket. Вы можете сделать это, используя некоторую форму передачи сообщений, будь то RPC или очередь сообщений.
Сам Ratchet основан на цикле событий React. Это означает, что любая форма связи с Ratchet должна быть интегрирована с этим циклом событий. На главной странице React вы можете увидеть некоторые из уже существующих интеграций:
В документации Ratchet есть учебник о том, как использовать React/ZMQ, чтобы выталкивать сообщения из любого места на ваш сервер WebSocket.
Ответ 2
Ratchet также реализует WAMP, который включает PubSub. Таким образом, ваши клиенты могут подписаться на некоторые темы, и вы можете публиковать на этих сайтах другие клиенты (работающие, например, на вашей внутренней инфраструктуре). Вы могли бы использовать публикацию клиента на основе AutobahnPython через Ratchet для мобильного приложения на базе AutobahnAndroid или для клиента HTML5 на базе AutobahnJS.
Ответ 3
У меня был тот же самый вопрос, и вот что я сделал.
На основе приветствия мирового учебника я заменил 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();
}
}
Конечно, чтобы сделать его действительно полезным, вы также можете добавить в соединение БД и сохранить/получить эти идентификаторы ресурсов.