2015-06-20 22 views
7

Tôi đang cố gắng xây dựng một hệ thống nơi người dùng có thể đăng ký một danh mục về thiết lập kết nối với máy chủ websocket và sau đó sẽ bắt đầu nhận cập nhật cho danh mục đó. Cho đến nay, tôi đã làm việc với Ratchet và tôi có thể gửi tin nhắn tới tất cả các khách hàng được kết nối nhưng vấn đề là tôi không muốn gửi tin nhắn tới tất cả khách hàng mà tôi chỉ muốn gửi tin nhắn tới các khách hàng đã đăng ký danh mục cụ thể trong đó thư được gửi.Cách gửi tin nhắn cho người dùng cụ thể Ratchet PHP Websocket

PHP Mã

Chat.php

<?php 
namespace MyApp; 
use Ratchet\MessageComponentInterface; 
use Ratchet\ConnectionInterface; 

class Chat implements MessageComponentInterface 
{ 
    protected $clients; 

    public function __construct() 
    { 
     $this->clients = new \SplObjectStorage; 
    } 

    public function onOpen(ConnectionInterface $conn) 
    { 
     $this->clients->attach($conn); 
    } 

    public function onMessage(ConnectionInterface $conn, $msg) 
    { 
     foreach ($this->clients as $client) 
     { 
      if($conn !== $client) 
       $client->send($msg); 
     } 
    } 

    public function onClose(ConnectionInterface $conn) 
    { 
     $this->clients->detach($conn); 
    } 

    public function onError(ConnectionInterface $conn, \Exception $e) 
    { 
     echo "An error has occurred: {$e->getMessage()}\n"; 
     $conn->close(); 
    } 
} 
?> 

server.php

<?php 
use Ratchet\Server\IoServer; 
use Ratchet\Http\HttpServer; 
use Ratchet\WebSocket\WsServer; 
use MyApp\Chat; 

require dirname(__DIR__) . '/Ratchet/vendor/autoload.php'; 

$server = IoServer::factory(
    new HttpServer(
    new WsServer(
     new Chat() 
    ) 
), 
    8080 
); 

$server->run(); 
?> 

Khách hàng bên js đang

<script type="text/javascript"> 
var conn = new WebSocket('ws://localhost:8080'); 

conn.onopen = function(e) { 
    console.log("Connection established!"); 
}; 

conn.onmessage = function(e) { 
    console.log(e.data); 
}; 
</script> 

Trả lời

21

Về cơ bản bạn muốn có một cú pháp cho việc gửi dữ liệu đến WebSocket, tôi reccom kết thúc bằng cách sử dụng một đối tượng JSON để làm điều này. Trong lớp WebSocket của bạn, bạn cần một biến cục bộ được gọi là subscriptions và một biến cục bộ được gọi là users giống như vậy.

<?php 
namespace MyApp; 
use Ratchet\MessageComponentInterface; 
use Ratchet\ConnectionInterface; 

class Chat implements MessageComponentInterface 
{ 
    protected $clients; 
    private $subscriptions; 
    private $users; 

    public function __construct() 
    { 
     $this->clients = new \SplObjectStorage; 
     $this->subscriptions = []; 
     $this->users = []; 
    } 

    public function onOpen(ConnectionInterface $conn) 
    { 
     $this->clients->attach($conn); 
     $this->users[$conn->resourceId] = $conn; 
    } 

    public function onMessage(ConnectionInterface $conn, $msg) 
    { 
     $data = json_decode($msg); 
     switch ($data->command) { 
      case "subscribe": 
       $this->subscriptions[$conn->resourceId] = $data->channel; 
       break; 
      case "message": 
       if (isset($this->subscriptions[$conn->resourceId])) { 
        $target = $this->subscriptions[$conn->resourceId]; 
        foreach ($this->subscriptions as $id=>$channel) { 
         if ($channel == $target && $id != $conn->resourceId) { 
          $this->users[$id]->send($data->message); 
         } 
        } 
       } 
     } 
    } 

    public function onClose(ConnectionInterface $conn) 
    { 
     $this->clients->detach($conn); 
     unset($this->users[$conn->resourceId]); 
     unset($this->subscriptions[$conn->resourceId]); 
    } 

    public function onError(ConnectionInterface $conn, \Exception $e) 
    { 
     echo "An error has occurred: {$e->getMessage()}\n"; 
     $conn->close(); 
    } 
} 
?> 

Các javascript để đi với điều đó trông hơi như thế này

<script type="text/javascript"> 
var conn = new WebSocket('ws://localhost:8080'); 

conn.onopen = function(e) { 
    console.log("Connection established!"); 
}; 

conn.onmessage = function(e) { 
    console.log(e.data); 
}; 

function subscribe(channel) { 
    conn.send(JSON.stringify({command: "subscribe", channel: channel})); 
} 

function sendMessage(msg) { 
    conn.send(JSON.stringify({command: "message", message: msg})); 
} 
</script> 

Lưu ý: Mã này là chưa được kiểm tra tôi đã viết nó khi đang bay từ kinh nghiệm của tôi với Ratchet. Chúc may mắn :)

+0

Thực ra tôi cần sử dụng Ratchet Pusher. Và tôi đã làm tất cả mọi thứ đang làm việc tốt nhưng bây giờ vấn đề là, rằng khách hàng bị ngắt kết nối sau vài phút được nhàn rỗi mà không có bất kỳ thông báo ngắt kết nối nó dừng nhận được tin nhắn. Nếu tôi tiếp tục gửi messing cho khách hàng trong mỗi 10 phút nó không ngắt kết nối, nhưng Nếu có một khoảng cách như hơn 20 phút hoặc lâu hơn, khách hàng không nhận được tin nhắn. –

+0

@RohitKhatri bạn đang sử dụng gì để kết nối với websocket? Bạn có proxy nó qua nginx hay gì đó không? – MarshallOfSound

+0

Tôi đang sử dụng Ratchet với Pusher từ ví dụ này [link] (http://socketo.me/docs/push) –

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