public function publish($topic, array $options = array()) { $this->checkPushService(); if (is_array($topic)) { foreach ($topic as $t) { $this->publish($t, $options); } return $this; } $self = $this; $timeout = isset($options['timeout']) ? $options['timeout'] : $this->timeout; $heartbeat = isset($options['heartbeat']) ? $options['heartbeat'] : $this->heartbeat; $this->topics[$topic] = new ArrayObject(); return $this->addFunction(function ($id) use($self, $topic, $timeout, $heartbeat) { $topics = $self->getTopics($topic); if (isset($topics[$id])) { if ($topics[$id]->count < 0) { $topics[$id]->count = 0; } $messages = $topics[$id]->messages; if (!$messages->isEmpty()) { $message = $messages->shift(); $message->detector->resolve(true); $self->resetTimer($topics, $topic, $id); return $message->result; } else { $self->delTimer($topics, $id); $topics[$id]->count++; } } else { $topics[$id] = new stdClass(); $topics[$id]->messages = new SplQueue(); $topics[$id]->count = 1; $topics[$id]->heartbeat = $heartbeat; $this->timer->setImmediate(function () use($self, $topic, $id) { $onSubscribe = $self->onSubscribe; if (is_callable($onSubscribe)) { call_user_func($onSubscribe, $topic, $id, $self); } }); } if (isset($topics[$id]->request)) { $topics[$id]->request->resolve(null); } $request = new Future(); $request->complete(function () use($topics, $id) { $topics[$id]->count--; }); $topics[$id]->request = $request; return $self->setRequestTimer($topic, $id, $request, $timeout); }, $topic); }