2018-04-15 23:54:30 +00:00
|
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
namespace NoccyLabs\Ipc\Interop\Channel;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* The MultiChannel is used to create a single channel and allow other threads
|
|
|
|
|
* to each grab an end of it. Think for example a web server that could write
|
|
|
|
|
* log output to a channel (as it´the MultiStreamChannel is always open); one
|
|
|
|
|
* thread could grab a channel to dump it to the console, and another thread
|
|
|
|
|
* could write to a logfile.
|
|
|
|
|
*/
|
|
|
|
|
class MultiStreamChannel implements ChannelInterface
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
protected $clients = [];
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Create a new client to receive data sent to the channel
|
|
|
|
|
*
|
|
|
|
|
* @return StreamChannel
|
|
|
|
|
*/
|
|
|
|
|
public function createClient(): StreamChannel
|
|
|
|
|
{
|
|
|
|
|
[ $a, $b ] = StreamChannel::createPair();
|
|
|
|
|
$this->clients[] = $a;
|
|
|
|
|
return $b;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* {@inheritDoc}
|
|
|
|
|
*
|
|
|
|
|
* @return boolean
|
|
|
|
|
*/
|
|
|
|
|
public function isOpen(): bool
|
|
|
|
|
{
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* {@inheritDoc}
|
|
|
|
|
*
|
|
|
|
|
* @param mixed $data
|
2018-04-16 00:52:51 +00:00
|
|
|
|
* @return bool
|
2018-04-15 23:54:30 +00:00
|
|
|
|
*/
|
2018-04-16 00:52:51 +00:00
|
|
|
|
public function send($data):bool
|
2018-04-15 23:54:30 +00:00
|
|
|
|
{
|
2018-04-16 00:52:51 +00:00
|
|
|
|
foreach ($this->clients as $i=>$client) {
|
|
|
|
|
if (false === $client->send($data)) {
|
|
|
|
|
unset($this->clients[$i]);
|
|
|
|
|
}
|
2018-04-15 23:54:30 +00:00
|
|
|
|
}
|
2018-04-16 00:52:51 +00:00
|
|
|
|
return true;
|
2018-04-15 23:54:30 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* {@inheritDoc}
|
|
|
|
|
*
|
|
|
|
|
* @return mixed
|
|
|
|
|
*/
|
|
|
|
|
public function receive()
|
|
|
|
|
{
|
|
|
|
|
foreach ($this->clients as $client) {
|
|
|
|
|
if ($read = $client->receive()) {
|
|
|
|
|
return $read;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|