public function __call($name, $args)
{
$request = new Deferred();
$promise = $request->promise();
$name = strtolower($name);
// special (p)(un)subscribe commands only accept a single parameter and have custom response logic applied
static $pubsubs = array('subscribe', 'unsubscribe', 'psubscribe', 'punsubscribe');
if ($this->ending) {
$request->reject(new RuntimeException('Connection closed'));
} elseif (count($args) !== 1 && in_array($name, $pubsubs)) {
$request->reject(new InvalidArgumentException('PubSub commands limited to single argument'));
} else {
$this->stream->write($this->serializer->getRequestMessage($name, $args));
$this->requests[] = $request;
}
if ($name === 'monitor') {
$monitoring =& $this->monitoring;
$promise->then(function () use(&$monitoring) {
$monitoring = true;
});
} elseif (in_array($name, $pubsubs)) {
$that = $this;
$subscribed =& $this->subscribed;
$psubscribed =& $this->psubscribed;
$promise->then(function ($array) use($that, &$subscribed, &$psubscribed) {
$first = array_shift($array);
// (p)(un)subscribe messages are to be forwarded
$that->emit($first, $array);
// remember number of (p)subscribe topics
if ($first === 'subscribe' || $first === 'unsubscribe') {
$subscribed = $array[1];
} else {
$psubscribed = $array[1];
}
});
}
return $promise;
}