2015-11-03 22 views
6

Tôi đang phát triển một ứng dụng web mà tôi cần phải hành vi thời gian thực cho các tình huống sau,PHP Ratchet WAMP Broadcast cho thuê bao trên công bố sự kiện

ứng dụng sẽ có hai loại người dùng PlayerSpectator. Người chơi có thể tham gia trò chơi đang diễn ra trong khi Người xem chỉ có thể tham gia trò chơi.

Trò chơi sẽ được người dùng quản trị khởi tạo.

Khán giả về cơ bản là ai đó người có thể xem danh sách người đã tham gia trò chơi. Tất nhiên điều này cần phải có ý nghĩa thời gian thực khi người chơi ngắt kết nối hoặc một người chơi mới tham gia vào một khán giả trò chơi sẽ thấy danh sách thời gian thực.

Để tóm tắt, hãy xem xét ví dụ dưới đây

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 

Xét một trên-đi trò chơi như một chủ đề/kênh (Ratchet\Wamp\Topic), tôi cần phải phát sóng để khán giả trên các sự kiện sau player joinplayer left vào trò chơi/chủ đề mà khán giả đã đăng ký.

Tôi đang sử dụng Ratchet WebSockets for PHP về phía máy chủ và autobahn js về phía khách hàng

Dưới đây là các mã. Cho đến nay tôi có thể gửi thông tin đến máy chủ (từ máy khách) khi người chơi tham gia/ngắt kết nối trò chơi. Nhưng Làm cách nào để phát sóng thông tin này đến khán giả (kết thúc của máy khách) khi người chơi tham gia hoặc ngắt kết nối.

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

Vì vậy, câu hỏi chính xác là gì? – Epodax

+0

Đầu tiên, -1 cho câu hỏi được hỏi (Bạn không thuê người ở đây). Thứ hai. Tôi thấy rằng bạn đang sử dụng hai cú pháp khác nhau từ hai phiên bản khác nhau của Autobahn (phiên bản triển khai WAMP v1 và phiên bản sử dụng WAMP v2). AFAIK, Mẫu PubSub được xử lý bởi lớp WAMPServer trong Ratchet chỉ tương thích với WAMP v1 và vì vậy bạn chỉ nên sử dụng Legacy AutobahnJS. Sẽ trở lại vì tôi cũng nghi ngờ về cách bạn triển khai đăng ký. –

+0

@whitelettersinblankpapers Tôi đã cố gắng sử dụng cú pháp khác để đăng ký và kết quả là không khác nhau. vui lòng kiểm tra câu hỏi được cập nhật –

Trả lời

1

Trước hết này câu trả lời có lẽ là quá muộn cho bạn mặc dù tôi sẽ trả lời nó cho hồ sơ.

Một khi bạn đã thiết lập nhiều kênh trong ứng dụng của bạn: spectator_GAME_ID

Bạn muốn có thể để xem ai đang chơi trò chơi mà bạn đang xem. Và lý do bạn đang sử dụng WebSocket là để bạn có thể thấy những thay đổi thời gian thực.

Trước tiên, bạn phải hiểu rằng Chủ đề là tất cả các kênh khác nhau/trò chơiId.

Khi bạn nhận ra điều này và sử dụng mã được cung cấp trên trang ví dụ của bản thân ratchet.

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

Trong ví dụ của họ, họ sử dụng các danh mục trong chuỗi JSON của bạn, bạn có thể sẽ thay đổi điều này thành gameId.

Khi bạn đã thực hiện điều này, bạn có thể gửi dữ liệu đến chỉ những người đang nghe một trò chơi nhất định.


Câu hỏi thứ hai là gửi cập nhật cho họ và cách biết cập nhật là gì.

Cách đơn giản nhất là bằng cách thêm một chuỗi các obejct JSON đang được gửi

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

Một khi điều này được gửi bạn sẽ nhận được nó trên clientside và kiểm tra các hành động, nếu hành động là 'tham gia' sau đó thêm tên người dùng đó vào một số danh sách. Nếu hành động là 'rời' thì hãy xóa tên người dùng đó khỏi danh sách.

Bạn có thể cập nhật màn hình của mình trong danh sách người chơi đang hoạt động với một số chức năng được gọi sau khi cập nhật hoặc sử dụng ng lặp lại đơn giản từ góc cạnh và sau đó chỉ áp dụng các giá trị mới cho nó.

Các vấn đề liên quan