2012-10-13 16 views
15

Chcę używać Ratchet (http://socketo.me) do stałego połączenia między aplikacjami iPhone i serwerem. Potrzebuję wymiany danych między aplikacjami i serwerem.Czy serwer Ratchet WebSocket może wysłać wiadomość do samego klienta?

Z tego przykładu (http://socketo.me/docs/hello-world) Mam okazało się, że mam funkcję onMessage która zostanie wywołana gdy App wysłać masaż do serwera, a serwer może wysłać odpowiedź do aplikacji.

Ale serwer musi również mieć możliwość wysyłania danych do aplikacji bez pobierania danych z aplikacji. Na przykład ustanowiono połączenie między aplikacją a serwerem. Coś stało się na serwerze i musimy wysłać nowe dane do aplikacji. Jak mogę to zrobić i czy to możliwe?

Główne pytanie brzmi: jak mogę przesłać dane do aplikacji z serwera?

Dziękuję za pomoc.

Odpowiedz

12

Jest to rzeczywiście możliwe. Musisz jakoś komunikować się z procesem serwera WebSocket. Możesz to zrobić, korzystając z jakiejś formy przekazywania wiadomości, czy to RPC, czy kolejki komunikatów.

Sama zapadka jest oparta na pętli zdarzeń React. Oznacza to, że każda forma komunikacji z Ratchetem musi być zintegrowana z tą pętlą zdarzeń. On the React homepage można zobaczyć niektóre z integracji, które już istnieją:

W dokumentacji Ratchet znajduje się a tutorial on how to use React/ZMQ w celu przesyłania wiadomości z dowolnego miejsca na serwer WebSocket.

+0

Dziękuję za pomoc. – lexa

+1

Dobry przykład dla React/ZMQ.Ale nie mogę się dowiedzieć, w jaki sposób mogę przekazać odpowiednie dane (na przykład specjalny json, który utworzyłem) odpowiedniemu użytkownikowi. Na przykład muszę wysłać dane do odpowiednich użytkowników (mam listy identyfikatorów użytkowników). Czy jest to konieczne, aby użytkownik był już subskrybowany do "określonej strony" (jak mówią tutaj: http://socketo.me/docs/push)? – lexa

+0

igorw, chmura, którą chcemy jakoś połączyć (skype, exmaple), aby zadać pytanie bezpośrednio Tobie. I dziękuję za pomoc. – lexa

6

Ratchet implementuje także WAMP, który obejmuje PubSub. Klienci mogą więc subskrybować niektóre tematy, a inni klienci (działający np. W infrastrukturze zaplecza) mogą publikować te tematy. Mógłbyś mieć klienta opartego na AutobahnPython, który publikowałby poprzez Ratchet na aplikacji mobilnej opartej na AutobahnAndroid lub na kliencie HTML5 opartym na AutobahnJS.

+0

używa wampv1, a iOS nie ma biblioteki dla wersji 1. Czy istnieje sposób na wykonanie funkcji push przy użyciu interfejsu MessageComponent? –

+0

Thruway obsługuje WAMPv2 https://github.com/voryx/Thruway, więc będziesz mógł używać https://github.com/mogui/MDWamp z nim – oberstet

0

Miałem dokładnie to samo pytanie i oto, co zrobiłem.

Na podstawie hello world tutorial, podstawiłem obiekt SplObjectStorage z tablicą. Zanim przedstawię moje modyfikacje, chciałbym powiedzieć, że jeśli wykonałeś ten samouczek i zrozumiałeś go, jedyną rzeczą, która uniemożliwiła ci samodzielne znalezienie tego rozwiązania, prawdopodobnie nie jest wiedza o tym, co to jest 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(); 
    } 
} 

Oczywiście, aby był naprawdę przydatny, możesz również dodać połączenie DB i zapisać/pobrać te identyfikatory zasobów.

+0

Działa niesamowicie !! Dziękujemy! – iYonatan

+1

Działa świetnie! ale działa to w pewien sposób, gdy serwer otrzyma wiadomość, którą wyślesz do klienta. Jak wysłać (zainicjować) wiadomość do klienta bez otrzymywania wiadomości od klienta – nepsdotin

Powiązane problemy