2014-11-26 3 views
-1

У меня есть сервер, у которого есть метод SendToAll ($ message). Мне нужен отдельный поток, который будет запускать этот метод (SendToAll) каждую секунду. Я использую pthreads.Метод выполнения в отдельной теме

class Sender extends Thread 
{ 
    public function __construct($server) 
    { 
     $this->server = $server; 
    } 

    public function run() 
    { 
     for (;;) { 
       $this->server->SendForAll("Hello"); 
       sleep(1); 
      } 
     } 
    } 
} 

Я создаю объект своего сервера и пытаюсь поместить его в конструкцию моего отправителя.

<?php 
require_once('includes.php'); 

runServer(); 

function runServer() 
{ 
    $server = new WssService("0.0.0.0", 9001); 
    $asyncOp = new Sender($server); 

    try { 
     $asyncOp->start(); 
     $server->StartServer(); 
    }catch (Exception $e) { 
     echo $e->getMessage(); 
     runServer(); 
    } 
} 

Но есть ошибка

Fatal error: Uncaught exception 'Exception' with message 'Serialization of 'Clos 
ure' is not allowed' in D:\xampp\htdocs\admin_p\classes\AsyncStorage.php:6 
Stack trace: 
#0 D:\xampp\htdocs\admin_p\classes\AsyncStorage.php(6): Sender::__construct() 
#1 D:\xampp\htdocs\admin_p\ss.php(9): Sender->__construct(Object(WssService)) 
#2 D:\xampp\htdocs\admin_p\ss.php(4): runServer() 
#3 {main} 
    thrown in D:\xampp\htdocs\admin_p\classes\AsyncStorage.php on line 6 

P.S. Извините, английский - это не мой родной язык.

class WssService 
{ 
    public $connects_storage = array(); 
    private $server = null; 
    private $logger = null; 
    private $writer = null; 
    public $loop = null; 

    public function __construct($URI, $port) 
    { 

     $this->connected_users = array(); 
     $this->loop = \React\EventLoop\Factory::create(); 
     $this->Logger = new \Zend\Log\Logger(); 
     $this->writer = new Zend\Log\Writer\Stream("php://output"); 
     $this->Logger->addWriter($this->writer); 
     $this->server = new WebSocketServer("tcp://" . $URI . ":" . $port, $this->loop, $this->Logger); 

     $this->server->on("connect", function (WebSocketTransportInterface $user) { 
      $this->Logger->notice((" Connected " . $user->getIp())); 
      array_push($this->connects_storage,$user); 
     }); 

     $this->server->on("disconnect", function (WebSocketTransportInterface $user) { 
      $this->Logger->notice((" Disconnected " . $user->getIp())); 
     }); 

     $this->server->on("message", function (WebSocketTransportInterface $s_user, WebSocketMessageInterface $message) { 
      $s_user->sendString($message); 
     }); 
    } 

    public function StartServer(){ 
     $this->server->bind(); 
     $this->loop->run(); 
    } 

    public function SendForAll($message){ 
     foreach($this->connects_storage as $client){ 
     $client->sendString($message); 
     } 
    } 
} 

Обновленный метод SendForAll()

public function SendForAll($message){ 
     echo var_export($message,true) .PHP_EOL; 
     echo var_dump($this->connects_storage).PHP_EOL; 

     if (count($this->connects_storage) > 0) { 
      foreach ($this->connects_storage as $client) { 
       $client->sendString($message); 
      } 
     } else echo "There are empty storage"; 
    } 

ответ

-1
$this->server->on("connect", function (WebSocketTransportInterface $user) { 
    $this->Logger->notice((" Connected " . $user->getIp())); 
    array_push($this->connects_storage,$user); 
}); 

$this->server->on("disconnect", function (WebSocketTransportInterface $user) { 
    $this->Logger->notice((" Disconnected " . $user->getIp())); 
}); 

$this->server->on("message", function (WebSocketTransportInterface $s_user, WebSocketMessageInterface $message) { 
    $s_user->sendString($message); 
}); 

Анонимные функции/закрытия не может быть сериализации. Вам нужно будет найти способ сохранить их по-разному.

Редактировать: Пришло время проверить этот код, (оказывается, вы не можете использовать pthreads с последним php). Во всяком случае, я был в состоянии решить вашу проблему, выполнив следующие действия:

Замените код выше:

$this->server->on("connect", new Jeremeamia\SuperClosure\SerializableClosure(function (WebSocketTransportInterface $user) { 
    $this->Logger->notice((" Connected " . $user->getIp())); 
    array_push($this->connects_storage,$user); 
})); 

$this->server->on("disconnect", new Jeremeamia\SuperClosure\SerializableClosure(function (WebSocketTransportInterface $user) { 
    $this->Logger->notice((" Disconnected " . $user->getIp())); 
})); 

$this->server->on("message", new Jeremeamia\SuperClosure\SerializableClosure(function (WebSocketTransportInterface $s_user, WebSocketMessageInterface $message) { 
    $s_user->sendString($message); 
})); 

После этого вам нужно будет включать в себя правильный library и, возможно, включают в себя правильные файлы (я как-то можно никогда не получайте композитора, чтобы правильно загружать файлы)

+0

Теперь я получаю « Фатальная ошибка: Не удается назначить ссылкой на перегруженный объект в D: \ XAMPP \ HTDOCS \ admin_p \ Классы \ AsyncStorage.php в строке 6» – Serg

+0

Где класс WssService от? – user254948

+0

PHP присваивает объекты по ссылке с версии ... моя память даже не растягивается. – Marek

-1

Ваш объект WssService не является сериализуемым. Для того, чтобы сделать это так, сделать $URL и $port переменные-члены, переместить инициализацию init() метода, а также осуществлять __sleep() и __wakeup() методы:

class WssService 
{ 
    protected $URI, $port; 
    public $connects_storage = array(); 
    private $server = null; 
    private $logger = null; 
    private $writer = null; 
    public $loop = null; 

    public function __construct($URI, $port) 
    { 
     $this->URI = $URI; 
     $this->port = $port; 
     $this->init(); 
    } 
    protected function init() { 
     $this->connected_users = array(); 
     $this->loop = \React\EventLoop\Factory::create(); 
     $this->Logger = new \Zend\Log\Logger(); 
     $this->writer = new Zend\Log\Writer\Stream("php://output"); 
     $this->Logger->addWriter($this->writer); 
     $this->server = new WebSocketServer("tcp://" . $this->URI . ":" . $this->port, $this->loop, $this->Logger); 

     $this->server->on("connect", function (WebSocketTransportInterface $user) { 
      $this->Logger->notice((" Connected " . $user->getIp())); 
      array_push($this->connects_storage,$user); 
     }); 

     $this->server->on("disconnect", function (WebSocketTransportInterface $user) { 
      $this->Logger->notice((" Disconnected " . $user->getIp())); 
     }); 

     $this->server->on("message", function (WebSocketTransportInterface $s_user, WebSocketMessageInterface $message) { 
      $s_user->sendString($message); 
     }); 
    } 

    public function StartServer(){ 
     $this->server->bind(); 
     $this->loop->run(); 
    } 

    public function SendForAll($message){ 
     foreach($this->connects_storage as $client){ 
     $client->sendString($message) 
     } 
    } 
    public function __sleep() { 
     return array('URI', 'port'); 
    } 
    public function __wakeup() { 
     $this->init(); 
    } 
} 

__sleep() говорит сериалайзер сериализовать только $URI и $port переменные, которые все, что вам нужно позвонить init() в __wakeup() во время несериализации.

+0

Когда я запускаю этот код, он сбой после запуска. – Serg

+0

Вы должны быть более конкретными. «Это грохот» ничего не говорит. – Marek

+0

Извините. Когда WssService начал объект метода отправки SendToAll(). Когда этот метод запускает сбой приложений без сообщений об ошибках. – Serg

Смежные вопросы