2016-07-25 16 views
8

Ich habe eine Ratchet-Server und Chat App Klasse, die gut läuft. Mein Problem ist, wie füge ich eine periodische Schleife hinzu?Wie greife ich auf die periodische Regelschleife mit Ratchet und den Client zu, der die App sendet?

Ich habe versucht, das Beispiel in Periodically sending mesages to clients in Ratchet

Aber ich habe immer nirgends zu folgen. Mein Ziel wie dieser Typ ist, dass der Server überprüft, ob alle Clients noch am Leben sind. Jedes Mal, wenn ich versuche, den addPeriodicTimer zu verwenden, kann ich anscheinend nicht auf die öffentliche Eigenschaft $ clients in der chat.php zugreifen, wie der Typ vom obigen Link, um Nachrichten vom Timer in server.php zu senden. Die foreach-Schleife im periodischen Timer in server.php beschwert sich, dass sie anscheinend ein "ungültiges Argument" hat.

Kann jemand sehen, was ich falsch mache?

mein server.php Code:

<?php 


require($_SERVER['DOCUMENT_ROOT'].'/var/www/html/vendor/autoload.php'); 
require_once($_SERVER['DOCUMENT_ROOT']."/var/www/html/bin/chat.php"); 

use Ratchet\Server\IoServer; 
use Ratchet\Http\HttpServer; 
use Ratchet\WebSocket\WsServer; 
use Ram\Chat; 


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

// Server timer <------ having trouble here 
$server->loop->addPeriodicTimer(5, function() use ($server) { 
foreach($server->app->clients as $client) 
{ 
    //$client->send("[helloworld]");  
} 
}); 


$server->run(); 
?> 

und meine chat.php:

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


error_reporting(E_ALL^E_NOTICE); 
session_id($_GET['sessid']); 
    if(!session_id) 
     session_start(); 


    $userid = $_SESSION["userid"]; 
    $username = $_SESSION["username"]; 
    $isadmin = $_SESSION["isadmin"]; 
    $resources = array(); 





    class Users 
    { 
     public $name; 
     public $resid; 
     public $timestamp; 



    } 



class Chat implements MessageComponentInterface 
{ 
    public $clients; 








    var $users = array(); 



    /* 
    function cmp($a, $b) 
    { 
     return strcmp($a->name, $b->name); 
    } 


    function removeObjectById(ConnectionInterface $id , $arr) 
    { 
     $array = $arr; 

     foreach ($array as $key => $element) { 
      if ($id->resourceId == $element->resid) 
      { 
       unset($array[$key]); 
       break; 
      } 
     } 

     usort($array, "cmp"); 

     return $array; 
    } 

    */ 




    public function __construct() 
    { 

     $this->clients = new \SplObjectStorage; 






    } 

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





    } 

    public function onClose(ConnectionInterface $conn) 
    { 

     //$users = removeObjectById($conn, $users); 

     $this->clients->detach($conn); 



    } 

    public function onMessage(ConnectionInterface $conn, $msg) 
    { 
     $msgjson = json_decode($msg); 
     $tag = $msgjson->tag; 

     if($tag == "[msgsend]") 
     { 

      foreach($this->clients as $client) 
      { 
        $client->send($msg);  
      } 
    } 
    else if($tag == "[bye]") 
    { 

     foreach($this->clients as $client) 
     { 
       $client->send($msg);  
     } 

     $this->clients->detach($conn); 
    } 
    else if($tag == "[connected]") 
    { 
     //store client information 
     $temp = new Users(); 
     $temp->name = $msgjson->uname; 
     $temp->resid = $conn->resourceId; 
     $temp->timestamp = date('Y-m-d H:i:s'); 

     $users[] = $temp; 

     //usort($users, "cmp"); 


     //send out messages 
      foreach($this->clients as $client) 
     { 
       $client->send($msg);  
     } 



    } 
    else if($tag == "[imalive]") 
    { 
     //update user timestamp who sent [imalive] 
     if (is_array($users) || is_object($users)) 
     { 
      foreach($users as $user) 
      { 
       if($msgjson->uname == $user->name) 
       { 
         $user->timestamp = date('Y-m-d H:i:s'); 
       } 
      } 
     } 
    } 







} 

public function onError(ConnectionInterface $conn, Exception $e) 
{ 
    echo "Error: " . $e->getMessage(); 
    $conn -> close(); 
} 

} 

?> 

Antwort

2

Warum nicht definieren die Chat Objektinstanz, bevor er in HTTPServer:

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

// Server timer <------ having trouble here 
$server->loop->addPeriodicTimer(5, function() use ($chat) { 
foreach($chat->clients as $client) 
{ 
    //$client->send("[helloworld]");  
} 
}); 


$server->run(); 
+0

kehrt: 'Kann nicht auf die geschützte Eigenschaft Chat \ Chat :: $ clients' zugreifen – maxisme

+0

Ich machte' $ clients' public is das gefährlich? – maxisme

+0

Es ist nicht das Beste aus Sicht der Programmierpraxis - es wäre wahrscheinlich besser, eine 'sendToAll' public Methode in' Chat' hinzuzufügen, die die Iteration und das Senden durchführt. – mbonneau