2016-07-16 8 views
0

私は定期的に "こんにちはの世界!" Chat.php:周期的にラチェットのクライアントにメッセージを送信する

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

class Chat implements MessageComponentInterface { 
    public $clients; 

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

    public function onOpen(ConnectionInterface $conn) { 
     // Store the new connection to send messages to later 
     $this->clients->attach($conn); 

     echo "New connection! ({$conn->resourceId})\n"; 
    } 

    //this worked but I don't want this behaviour 
    public function onMessage(ConnectionInterface $from, $msg) { 
     /*$numRecv = count($this->clients) - 1; 
     echo sprintf('Connection %d sending message "%s" to %d other connection%s' . "\n" 
      , $from->resourceId, $msg, $numRecv, $numRecv == 1 ? '' : 's'); 

     foreach ($this->clients as $client) { 
      if ($from !== $client) { 
       // The sender is not the receiver, send to each client connected 
       $client->send($msg); 
      } 
     }*/ 
    } 

    public function onClose(ConnectionInterface $conn) { 
     // The connection is closed, remove it, as we can no longer send it messages 
     $this->clients->detach($conn); 

     echo "Connection {$conn->resourceId} has disconnected\n"; 
    } 

    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 MyApp\Chat; 

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

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

    $server->run(); 
ラチェットのチュートリアルからチャットサーバーに接続しているすべてのクライアントへのメッセージは

私はここですべてのコードを掲載します

は、私は、サーバーのループにタイマーを追加どのように私は理解し、ドキュメントの多くをテストするには

<?php 
    use Ratchet\Server\IoServer; 
    use MyApp\Chat; 

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

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


     // My code here 
     $server->loop->addPeriodicTimer(5, function() { 
      echo "custom loop timer working !";   
     }); 


     $server->run(); 

とそれはサーバーを起動した後5秒ごとにその文字列を出力して正常に動作しました。

は、今私はそうのようにそれをやってみました、MessageComponentInterfaceに保存されているクライアントにメッセージを送信しようとすると、チュートリアル

$server->loop->addPeriodicTimer(5, function() {   
    foreach ($server->app->clients as $client) {     
      $client->send("hello client");   
    } 
}); 

からチャットと呼ばれるしかし、私は$サーバ - >アプリがあるNULLであることを取得していますおそらく私は今function()ブロックの中にいるからです。オブジェクト指向のPHPについては専門家ではありません。この小さなプロジェクトが私には大いに役立ちます。 MessageComponentInterfaceにアクセスして、タイマー内のサーバーのappプロパティを呼び出すと、そこに格納されているクライアントにデータを送信できますか?

+0

($サーバー)を使用し、 '追加'関数 '後に()' –

+0

'クロージャはまた、変数を継承することができます親スコープから削除します。そのような変数は使用言語構造体に渡さなければなりません.' https://secure.php.net/manual/en/functions.anonymous.php –

+0

'$ server'はクロージャーでは定義されていないのでNULLです関数スコープそれについての詳細はこちらhttps://secure.php.net/manual/en/language.variables.scope.php –

答えて

2

$serverは関数スコープで定義されておらず、親スコープの変数はデフォルトで子スコープに継承されません。クロージャは、use言語構造を使用して親スコープから変数を継承できます。匿名関数(クロージャ)に関する

$server->loop->addPeriodicTimer(5, function() use ($server) {   
    foreach ($server->app->clients as $client) {     
      $client->send("hello client");   
    } 
}); 

詳細情報:https://secure.php.net/manual/en/functions.anonymous.php
変数のスコープについての詳細情報:https://secure.php.net/manual/en/language.variables.scope.php

関連する問題