2015-11-03 40 views
6

Zajmuję się tworzeniem aplikacji internetowych, gdzie potrzeba zachowania czasie rzeczywistym następującym scenariuszuPHP Ratchet Wamp Broadcast abonentom na publikowanie zdarzenie

Zastosowanie będą miały dwa rodzaje użytkowników Player i Spectator. Gracze mogą przyłączyć się do bieżącej gry, podczas gdy Widz może zwyczajnie spoglądać.

Gra zostanie zainicjowana przez administratora.

Widzem jest w zasadzie ktoś , który widzi listę osób, którzy dołączyli do gry. Oczywiście musi to być w czasie rzeczywistym, gdy gracz się rozłącza lub nowy gracz dołącza do widza gry widzi listę czasu rzeczywistego.

Podsumowując, należy rozważyć przykład poniżej

Spectator_1 joins Clan_101 
Spectator_2 joins Clan_201 

Player_1 joins Clan_101 // Need to broadcast this event to Spectator_1 
Player_2 joins Clan_101 // Need to broadcast this event to Spectator_1 
Player_1 disconnects Clan_101 // // Need to broadcast this event to Spectator_1 

Player_11 joins Clan_201 // Need to broadcast this event to Spectator_2 
Player_12 joins Clan_201 // // Need to broadcast this event to Spectator_2 

Biorąc pod uwagę w toku gry jako temat/kanał (Ratchet\Wamp\Topic), muszę się nadawać do widzów na następujących imprezach player join i player left do gry/temat, który widzowie zasubskrybowali.

Używam Ratchet WebSockets for PHP po stronie serwera i po stronie klienta autobahn js

Poniżej znajduje się kod. Do tej pory mogę przesłać informacje do serwera (od klienta), gdy gracz dołącza/odłącza grę. Ale jak mogę przekazać te informacje do widzów (koniec klienta), gdy gracz dołącza lub rozłącza.

player.html

<script src="scripts/autobahn.js" type="text/javascript"></script> 
<script src="scripts/jquery-1.11.2.min.js" type="text/javascript"></script> 
<script> 
ab.connect(
    'ws://localhost:8080', 
    function (session) { 
     appSession = session; 
     $('#btnJoinGame').on('click',function(){ 
     session.publish('joingame', ['data','GAME_ID']); 
    });     
}); 
</script> 

spectator.html

<script> 
var conn = new ab.Session(
    'ws://localhost:8080', 
    function() {    
     conn.subscribe('spectator_GAME_ID', function(topic, data) { 
      console.log(topic); 
      console.log(data); 
     }); 
    }, 
    function() {    
     console.warn('WebSocket connection closed'); 
    }  
); 
/* OR Using the legacy syntax */ 
/* 
    ab.connect(
     'ws://localhost:8080', 
      function (session) { 
       session.subscribe("t1011", function (topic, event) { 
        console.log(event); 
       }); 
      }      
    ); 
*/ 
</script> 

server.php

require __DIR__ . '/vendor/autoload.php'; 

use Ratchet\Wamp\WampServerInterface; 
use Ratchet\MessageComponentInterface; 
use Ratchet\ConnectionInterface as Conn; 


class EventHandler implements WampServerInterface, MessageComponentInterface{ 
    public function __construct(React\EventLoop\StreamSelectLoop $loop){ 
     $this->loop = $loop; 
    } 
    public function onSubscribe(Conn $conn, $subscription, $params = array()){ 
     $subscription->broadcast($this->data); 
    } 

    public function onPublish(Conn $conn, $topic, $params, array $exclude, array $eligible) { 
     if($topic->getId() === 'joingame'){ 
      if(!isset($this->data[$params[1]])){ 
       $this->data[$params[1]] = array($params[0]); 
      }else{ 
       array_push($this->data[$params[1]], $params[0]); 
      }    
     } 
     /** DOES'NT WORKS **/ 
     $newtopic = new Ratchet\Wamp\Topic('spectator_GAME_ID'); 
     $this->onSubscribe($conn,$newtopic); 
    } 
    /*Omitting other methods for brevity*/ 
} 

$loop = React\EventLoop\Factory::create(); 

$webSock = new React\Socket\Server($loop); 
$webSock->listen(8080, '0.0.0.0'); // Binding to 0.0.0.0 means remotes can connect 
new Ratchet\Server\IoServer(
    new Ratchet\Http\HttpServer( 
     new Ratchet\WebSocket\WsServer(
      new Ratchet\Wamp\WampServer(
       new EventHandler($loop) // This is my class. Pass in the loop! 
      ) 
     ) 
    ), 
    $webSock 
); 

$loop->run(); 
+0

Jakie jest dokładnie pytanie? – Epodax

+0

Po pierwsze -1 za sposób zadawania pytania (nie zatrudniacie tutaj ludzi). Po drugie. Widzę, że używasz dwóch różnych składni dwóch różnych wersji Autobahn (wersja implementująca WAMP v1 i ta używająca WAMP v2). AFAIK, wzorzec PubSub obsługiwany przez klasę WAMPServer w Ratchet jest kompatybilny tylko z WAMP v1, więc powinieneś używać tylko Legacy AutobahnJS. Wróci, ponieważ mam również wątpliwości co do sposobu wdrożenia subskrypcji. –

+0

@whitelettersinblankpapers Próbowałem użyć innej składni do subskrybowania, a wynik nie jest inny. sprawdź zaktualizowane pytanie –

Odpowiedz

1

Przede wszystkim to odpowiedź jest już prawdopodobnie dla ciebie za późno, chociaż odpowiem na nią za rekord.

Po nawiązaniu wielu kanałów w aplikacji: spectator_GAME_ID

Chcesz być w stanie zobaczyć, kto gra w gry, który właśnie oglądasz. A powodem, dla którego używasz WebSocket, jest możliwość zobaczenia zmian w czasie rzeczywistym.

Przede wszystkim musisz zrozumieć, że tematy są różnymi kanałami/grami.

Kiedy już to sobie uświadomisz i wykorzystasz kod podany na przykładowej stronie zapadki.

$entryData = json_decode($entry, true); 

    // If the lookup topic object isn't set there is no one to publish to 
    if (!array_key_exists($entryData['category'], $this->subscribedTopics)) { 
     return; 
    } 

    $topic = $this->subscribedTopics[$entryData['category']]; 

    // re-send the data to all the clients subscribed to that category 
    $topic->broadcast($entryData); 

W swoim przykładzie używają kategorii w swoim ciągu JSON prawdopodobnie zmienisz to na gameId.

Gdy już to zainstalujesz, będziesz mógł wysyłać dane tylko do osób, które nasłuchują na dany identyfikator gry.


Druga część pytania dotyczyła wysyłania aktualizacji i sposobu sprawdzania aktualizacji.

Najprostszym sposobem jest dodanie ciąg do obejct JSON, który jest wysłany

{ 
    "action": "join", 
    "gameId": "123",     //so that you know to which game to publish it 
    "userIdThatJoined": "123456789", //whatever other data you need 
    "userNameThatJoined": "Foo Bar" 
} 

Po tym zostaje wysłany powinna pojawić się na stronie klienta i sprawdzić działanie, jeżeli działanie jest „przyłączyć” następnie dodaj tego użytkownika do swojej listy. Jeśli akcja jest "pozostaw", usuń tego użytkownika z listy.

Możesz zaktualizować swój wyświetlacz na liście aktywnych graczy za pomocą funkcji, która jest wywoływana po aktualizacji lub użyć prostego ng-repeat z kątowego, a następnie zastosować do niej nowe wartości.