2015-11-03 12 views
6

Ich bin eine Web-Anwendung zu entwickeln, wo ich für das folgende Szenario Echtzeitverhalten benötigen,PHP Ratchet Wamp Broadcast Abonnenten veröffentlicht auf Ereignis

Anwendung zwei Arten von Benutzern hat Player und Spectator. Spieler können an einem laufenden Spiel teilnehmen, während Zuschauer nur zuschauen können.

Ein Spiel wird von einem Admin-Benutzer initialisiert.

Ein Zuschauer ist im Grunde jemand wer die Liste der Leute sehen kann, die einem Spiel beigetreten sind. Natürlich muss dies eine Echtzeit-Bedeutung sein, wenn ein Spieler die Verbindung trennt oder ein neuer Spieler einem Spielzuschauer beitritt, sieht er die Echtzeit-Liste.

Zusammenfassend betrachten das folgende Beispiel

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 

In Anbetracht einer laufenden Spiel als Thema/Kanal (Ratchet\Wamp\Topic), muss ich für die Zuschauer auf den folgenden Veranstaltungen player join und player left, um das Spiel übertragen/Thema, auf dem Zuschauer abonniert haben.

I Ratchet WebSockets for PHP auf Server-Seite bin mit und autobahn js auf Client-Seite

Unten ist der Code. So weit, wo ich Informationen zum Server (vom Client) senden kann, wenn ein Spieler einem Spiel beitritt/trennt. Aber wie sende ich diese Informationen an Zuschauer (Client-Ende), wenn ein Spieler beitritt oder die Verbindung trennt.

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

, was ist die Frage genau? – Epodax

+0

Zuerst -1 für die Art und Weise, wie die Frage gestellt wurde (Sie stellen keine Leute hier ein). Zweitens. Ich sehe, dass Sie zwei verschiedene Syntaxen aus zwei verschiedenen Versionen von Autobahn verwenden (die Version, die WAMP v1 und die mit WAMP v2 implementiert). AFAIK, das PubSub Muster behandelt durch WAMPServer Klasse in Ratchet ist nur mit WAMP v1 kompatibel und so sollten Sie nur Legacy-AutobahnJS verwenden. Werde zurückkommen, da ich auch Zweifel habe, wie du das Abo implementiert hast. –

+0

@whileletsinblankpapers Ich habe versucht, die andere Syntax für Abonnieren und das Ergebnis ist nicht anders. Bitte überprüfen Sie die aktualisierte Frage –

Antwort

1

Zuerst einmal Antwort ist wahrscheinlich schon zu spät für dich, obwohl ich es für die Aufzeichnung beantworten werde.

Sobald Sie mehrere Kanäle in der Anwendung etabliert haben: spectator_GAME_ID

Sie wollen in der Lage sein zu sehen, wer das Spiel spielt, die Sie beobachten. Und der Grund, warum Sie einen WebSocket verwenden, ist, dass Sie Änderungen in Echtzeit sehen können.

Zuerst müssen Sie verstehen, dass die Themen alle verschiedene Kanäle/gameId sind.

Sobald Sie dies erkennen und den Code verwenden, der auf der Beispielseite der Ratsche selbst zur Verfügung gestellt wird.

$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); 

In ihrem Beispiel verwenden sie Kategorien in ihrer JSON-Zeichenfolge, die Sie wahrscheinlich zu gameId ändern werden.

Sobald Sie dies an Ort und Stelle haben, können Sie Daten nur an die Personen senden, die auf eine bestimmte gameId warten.


Zweiter Teil Ihrer Frage war, Updates an sie zu senden und zu wissen, was das Update ist.

Der einfachste Weg ist durch einen String an das JSON obejct hinzufügen, die

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

gesendet wird Sobald diese gesendet wird, können Sie es auf Clientside erhalten sollte und für die Aktion überprüfen, ob die Aktion ‚nachziehen‘ Fügen Sie dann diesem Benutzer seinen Namen zu einer Liste hinzu. Wenn die Aktion 'verlassen' ist, dann entferne diesen Benutzer aus der Liste.

Sie können Ihre Anzeige in der Liste der aktiven Spieler mit einer gewissen Funktion aktualisieren, die nach einem Update oder verwenden Sie eine einfache ng-Repeat von Winkel- und dann gelten nur die neuen Werte sie aufgerufen wird. So