我正在开发一个Web应用程序,我需要以下场景的实时行为,
应用程序将有两种类型的用户Player
和Spectator
。玩家可以加入正在进行的游戏,而观众只能观看。
游戏将由管理员用户初始化。
观众基本上是可以看到已加入游戏的人员列表的人。当然,当玩家断开连接或新玩家加入游戏观众时,这需要是实时意义。
总结一下,请考虑以下示例
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 join
和player 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 :(得分:1)
首先,这个答案对你来说可能已经太晚了,虽然我会回答它的记录。
在您的应用中建立多个频道后: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的人发送数据。
问题的第二部分是向他们发送更新以及如何知道更新的内容。
最简单的方法是向正在发送的JSON obejct添加一个字符串
{
"action": "join",
"gameId": "123", //so that you know to which game to publish it
"userIdThatJoined": "123456789", //whatever other data you need
"userNameThatJoined": "Foo Bar"
}
发送后,您应该在客户端收到并检查操作,如果操作是“加入”,则将该用户的名字添加到某个列表中。如果操作是“离开”,则从列表中删除该用户的姓名。
您可以使用在更新后调用的某些函数更新活动播放器列表中的显示,或者使用角度的简单ng-repeat,然后将新值应用于它。