PHP棘轮WAMP广播给用户在发布事件

问题描述:

我开发一个Web应用程序,我需要对以下情形的实时行为,PHP棘轮WAMP广播给用户在发布事件

应用将有两个类型的用户PlayerSpectator的。玩家可以参加即将开始的比赛,观众只能观看比赛。

游戏将由管理员用户初始化。

旁观者基本上是某人谁可以看到谁加入了游戏的人名单。当玩家断线或者新玩家加入游戏观众时,这当然需要具有实时意义,才能看到实时列表。

总之,考虑下面的例子

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 

考虑一个持续的游戏为主题/通道(Ratchet\Wamp\Topic),我需要广播给观众以下事件player joinplayer left游戏/观众已订阅的主题。

我在客户端

下面使用Ratchet WebSockets for PHP在服务器端和autobahn js是代码。到目前为止,当玩家加入/断开游戏时,我可以向服务器发送信息(来自客户端)。 但是,当玩家加入或断开连接时,如何将此信息广播至观众(客户端)。

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

那么,究竟是什么问题呢? – Epodax

+0

首先,-1提问的方式(你不是在这里招聘人员)。其次,我看到你使用两种不同版本的Autobahn(实现WAMP v1的版本和使用WAMP v2的版本)的两种不同语法。 AFAIK,由Ratchet的WAMPServer类处理的PubSub模式只与WAMP v1兼容,因此您只能使用Legacy AutobahnJS。将回来,因为我也怀疑你实施订阅的方式。 –

+0

@whitelettersinblankpapers我试图使用其他语法进行订阅和结果没有什么不同。请检查更新后的问题 –

首先,这答案可能已经太迟了,虽然我会回答记录。

一旦你已经在你的应用程序建立多种渠道:spectator_GAME_ID

你希望能够看到谁打你正在看比赛。你使用WebSocket的原因是你可以看到实时变化。

你首先必须明白,主题是所有不同的渠道/ gameId的。

一旦你意识到这一点,并使用棘轮本身的示例页面上提供的代码。

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

在他们的例子中,他们在他们的JSON字符串中使用类别,您可能会将其更改为gameId。

一旦你有这个地方,你就可以发送数据给只有听取某个gameId的人。


问题的第二部分是向他们发送更新以及如何知道更新是什么。

最简单的方法是添加一个字符串,正在发送

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

一旦这个送你应该得到它在客户方和检查的动作,如果动作是“加入”的JSON obejct然后将该用户的姓名添加到某个列表中。如果该行为是“离开”,则从该列表中删除该用户的他/她的名字。

你可以使用一些更新后调用的函数来更新你的显示在活动播放器列表中,或者使用一个简单的ng-repeat从角度,然后将新的值应用到它。