PhpDaemon+взаимодействие клиентов

254 views
Skip to first unread message

Alexey Kolchin

unread,
Nov 25, 2016, 12:33:21 AM11/25/16
to phpdaemon
Добрый день,

Недавно начал работать с PhpDaemon и веб-сокетами вообще, поэтому могу что-то не так понимать, но решения в интернете не нашел.
Задача такая: есть страница с формой, и нужно, чтобы текст, который вводит в поле один посетитель, видели сразу все остальные посетители.
Код на данный момент такой:
class MyWebSocket extends \PHPDaemon\Core\AppInstance {
public $enableRPC=true;
public $sessions=array();
public function onReady() {
$appInstance = $this;
$this->timerTask($appInstance);
\PHPDaemon\Servers\WebSocket\Pool::getInstance()->addRoute('myws', function ($client) use ($appInstance) {
$session=new MyWebSocketRoute($client, $appInstance);
$session->id=uniqid();
$this->sessions[$session->id]=$session;
return $session;
});
}
function timerTask($appInstance) {
\PHPDaemon\Core\Timer::add(function($event) use ($appInstance) {
$this->timerTask($appInstance);
$event->finish();
}, 5e6);
}
public function sendBcMessage($pid) {
foreach($this->sessions as $id=>$session) {
$session->client->sendFrame('This is broadcast message from worker #'.$pid, 'STRING');
}
}
}
class MyWebSocketRoute extends \PHPDaemon\WebSocket\Route {
public $client;
public $appInstance;
public $id;
public function __construct($client,$appInstance) {
$this->client=$client;
$this->appInstance=$appInstance;
}
public function onFrame($data, $type) {
                $m = array();
                if (preg_match('/block (.*?)/',$data,$m)){
                  $appInstance = $this->appInstance;
   foreach($appInstance->sessions as $s_id=>$session) {
//                     if ($s_id!=$this->id){
      $session->client->sendFrame('Block "'.$m[1].'"'.print_r($m,1).print_r(array_keys($appInstance->sessions),1), 'STRING');
//                     }
 }
                }else{
    $this->client->sendFrame('Server receive from client #'.$this->id.' message "'.$data.'"', 'STRING');
                }
}
public function onFinish() {
unset($this->appInstance->sessions[$this->id]);
}
}
При этом на странице с формой по oninput шлется в веб-сокет сообщение "block "+id поля.
Но как обнаруживается, когда эта страница открыта в нескольких браузерах, во многих случаях они видит не все имеющихся клиентов (то есть array_keys($appInstance->sessions) может содержать информацию не о всех открытых страницах), причем, похоже, непредсказуемо, сколько клиентов она увидит. 
Почему так происходит, и можно ли как-нибудь получить полную информацию?

Vasily Zorin

unread,
Nov 25, 2016, 1:20:43 AM11/25/16
to phpd...@googlegroups.com
Это происходит потому что у вас больше одного рабочего процесса. Не стоит полагаться на $this->appInstance->sessions

--

---
Вы получили это сообщение, поскольку подписаны на группу "phpdaemon".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес phpdaemon+unsubscribe@googlegroups.com.
Чтобы настроить другие параметры, перейдите по ссылке https://groups.google.com/d/optout.

Vasily Zorin

unread,
Nov 25, 2016, 1:20:57 AM11/25/16
to phpd...@googlegroups.com
Используйте Redis PUB/SUB

Oleksiy Sukhy

unread,
Nov 28, 2016, 2:58:53 AM11/28/16
to phpdaemon
я решал это через такой хитрый метод как $appInstance->broadcastCall($method, $args = [], $cb = null)
будучи вызванным из любого места любого рабочего процесса они инициирует вызов указанного метода во ВСЕХ активных рабочих процессах
Reply all
Reply to author
Forward
0 new messages