/** * Register a listener to be notified when a stream is ready to read. * * @param stream $stream The PHP stream resource to check. * @param callable $listener Invoked when the stream is ready. */ public function addReadStream($stream, callable $listener) { $this->emit('addReadStream', [$stream, $listener]); $this->loop->addReadStream($stream, function ($stream) use($listener) { $this->emit('readStreamTick', [$stream, $listener]); $listener($stream, $this); }); }
/** * @param $data * @param null $remoteAddress * @param bool $waitForResponse * @return Observable */ public function write($data, $remoteAddress = null, $waitForResponse = true) { $buffer = new Buffer($this->socket, $this->loop, $data, $remoteAddress); $buffer->subscribeCallback(null, [$this, "close"], function () use($waitForResponse) { if ($waitForResponse) { $this->loop->addReadStream($this->socket, array($this, 'read')); } else { $this->notifyCompleted(); } }); return $buffer; }
/** * Adds a path to the list of watched paths * * @param string $path Path to the watched file or directory * @param integer $mask Bitmask of inotify constants * @return integer unique watch identifier, can be used to remove() watch later */ public function add($path, $mask) { if ($this->inotifyHandler === false) { // inotifyHandler not started yet => start a new one $this->inotifyHandler = \inotify_init(); stream_set_blocking($this->inotifyHandler, 0); // wait for any file events by reading from inotify handler asynchronously $this->loop->addReadStream($this->inotifyHandler, $this); } $descriptor = \inotify_add_watch($this->inotifyHandler, $path, $mask); $this->watchDescriptors[$descriptor] = array('path' => $path); return $descriptor; }
protected function init($callback) { foreach ($this->addresses as $address) { $socket = stream_socket_client("tcp://{$address['ip']}:{$address['port']}", $error_no, $error_str, 30); if ($socket === false) { } $this->loop->addReadStream($socket, function ($socket) use($callback) { //½âÂë //»Øµ÷ call_user_func($callback); }); $this->streams[$address['ip'] . ':' . $address['port']] = $socket; } }
/** * Add event listener to event loop. * * @param $fd * @param $flag * @param $func * @param array $args * @return bool */ public function add($fd, $flag, $func, $args = array()) { switch ($flag) { case EventInterface::EV_READ: return $this->_loop->addReadStream($fd, $func); case EventInterface::EV_WRITE: return $this->_loop->addWriteStream($fd, $func); case EventInterface::EV_SIGNAL: return $this->_loop->addSignal($fd, $func); case EventInterface::EV_TIMER: return $this->_loop->addPeriodicTimer($fd, $func); case EventInterface::EV_TIMER_ONCE: return $this->_loop->addTimer($fd, $func); } return false; }
/** * Connects to AMQP server. * * Calling connect() multiple times will result in error. * * @return Promise\PromiseInterface */ public function connect() { if ($this->state !== ClientStateEnum::NOT_CONNECTED) { return Promise\reject(new ClientException("Client already connected/connecting.")); } $this->state = ClientStateEnum::CONNECTING; $this->writer->appendProtocolHeader($this->writeBuffer); try { $this->eventLoop->addReadStream($this->getStream(), [$this, "onDataAvailable"]); } catch (\Exception $e) { return Promise\reject($e); } return $this->flushWriteBuffer()->then(function () { return $this->awaitConnectionStart(); })->then(function (MethodConnectionStartFrame $start) { return $this->authResponse($start); })->then(function () { return $this->awaitConnectionTune(); })->then(function (MethodConnectionTuneFrame $tune) { $this->frameMax = $tune->frameMax; return $this->connectionTuneOk($tune->channelMax, $tune->frameMax, $this->options["heartbeat"]); })->then(function () { return $this->connectionOpen($this->options["vhost"]); })->then(function () { $this->heartbeatTimer = $this->eventLoop->addTimer($this->options["heartbeat"], [$this, "onHeartbeat"]); $this->state = ClientStateEnum::CONNECTED; return $this; }); }
function it_adds_a_read_stream($socket, ChannelInterface $channel, ConnectionInterface $connection, LoopInterface $loop) { $channel->getConnection()->willReturn($connection); $connection->getSocket()->willReturn($socket); $loop->addReadStream($socket, [$this, 'wait'])->shouldBeCalled(); $this->beConstructedWith($channel, $loop); }
protected function register() { if ($this->active) { return; } $this->active = true; $this->loop->addReadStream($this->fd, [$this, 'handleEvent']); }
public function connect($server) { $this->state = self::STATE_BUSY; $this->stream = stream_socket_client($server, $this->errno, $this->errstr); $this->loop->addReadStream($this->stream, [$this, 'process']); if (fwrite($this->stream, "helo hi\r\n") === false) { $this->state = self::STATE_DISCONNECTED; $this->onFailure->__invoke($this->record, "Error while sending helo"); echo $this->errno . ': ' . $this->errstr . PHP_EOL; return; } if (fwrite($this->stream, "mail from: <test." . mt_rand(0, 99999) . "@example.com>\r\n") === false) { $this->state = self::STATE_DISCONNECTED; $this->onFailure->__invoke($this->record, "Error while sending from"); echo $this->errno . ': ' . $this->errstr . PHP_EOL; return; } }
/** * Starts shell */ public function run() { if ($this->running) { return; } $shell = $this; $this->loop->addReadStream(STDIN, function ($n) use($shell) { $c = stream_get_contents($n, 1); $shell->read($c); }); // allows control keys to work if (function_exists('readline_callback_handler_install')) { readline_callback_handler_install('', function () { }); } $this->running = true; $this->loop->run(); }
/** @test */ public function stopShouldStopRunningLoop() { $input = $this->createStream(); $loop = $this->loop; $this->loop->addReadStream($input, function ($stream) use($loop) { $loop->stop(); }); $this->writeToStream($input, "foo\n"); $this->assertRunFasterThan(0.005); }
/** * Start the server by listening on a specified port and address. * @param int $port * @param string $host * @throws ConnectionException */ public function listen($port, $host = '0.0.0.0') { if (strpos($host, ':') !== false) { // enclose IPv6 addresses in square brackets before appending port $host = '[' . $host . ']'; } $this->master = stream_socket_server("tcp://{$host}:{$port}", $errorNumber, $errorString); if (false === $this->master) { $message = "Could not bind to tcp://{$host}:{$port}: {$errorString}"; throw new ConnectionException($message, $errorNumber); } stream_set_blocking($this->master, 0); $this->loop->addReadStream($this->master, function ($master) { $newSocket = @stream_socket_accept($master); if (false === $newSocket) { $this->emit('error', array(new \RuntimeException('Error accepting new connection'))); return; } $this->handleConnection($newSocket); }); }
/** * Watch a stream resource for IO readable data and trigger the callback when actionable * * @param resource $stream A stream resource to watch for readable data * @param callable $callback Any valid PHP callable * @param bool $enableNow Should the watcher be enabled now or held for later use? * @return int */ public function onReadable($stream, callable $callback, $enableNow = true) { $watcherId = null; $this->reactor->addReadStream($stream, function () use($callback, &$watcherId, $stream) { if (isset($this->disabledWatchers[$watcherId])) { return null; } return call_user_func($callback, $watcherId, $stream, $this); }); $watcherId = $this->registerWatcher(self::WATCHER_TYPE_READ, $stream); if (!$enableNow) { $this->disable($watcherId); } return $watcherId; }
/** * Subscribe to topic/channel * * @param string $topic A valid topic name: [.a-zA-Z0-9_-] and 1 < length < 32 * @param string $channel Our channel name: [.a-zA-Z0-9_-] and 1 < length < 32 * "In practice, a channel maps to a downstream service consuming a topic." * @param callable $callback A callback that will be executed with a single * parameter of the message object dequeued. Simply return TRUE to * mark the message as finished or throw an exception to cause a * backed-off requeue * * @throws \RuntimeException If we don't have a valid callback * @throws \InvalidArgumentException If we don't have a valid callback * * @return nsqphp This instance of call chaining */ public function subscribe($topic, $channel, $callback) { if ($this->nsLookup === NULL) { throw new \RuntimeException('nsqphp initialised without providing lookup service (required for sub).'); } if (!is_callable($callback)) { throw new \InvalidArgumentException('"callback" invalid; expecting a PHP callable'); } // we need to instantiate a new connection for every nsqd that we need // to fetch messages from for this topic/channel $hosts = $this->nsLookup->lookupHosts($topic); if ($this->logger) { $this->logger->debug("Found the following hosts for topic \"{$topic}\": " . implode(',', $hosts)); } foreach ($hosts as $host) { $parts = explode(':', $host); $conn = new Connection\Connection($parts[0], isset($parts[1]) ? $parts[1] : NULL, $this->connectionTimeout, $this->readWriteTimeout, $this->readWaitTimeout, TRUE); if ($this->logger) { $this->logger->info("Connecting to {$host} and saying hello"); } $conn->write($this->writer->magic()); $this->subConnectionPool->add($conn); $socket = $conn->getSocket(); $nsq = $this; $this->loop->addReadStream($socket, function ($socket) use($nsq, $callback, $topic, $channel) { $nsq->readAndDispatchMessage($socket, $topic, $channel, $callback); }); // subscribe $conn->write($this->writer->subscribe($topic, $channel, $this->shortId, $this->longId)); $conn->write($this->writer->ready(1)); } return $this; }
public function attachReadListener() { $this->loop->addReadStream($this->fileDescriptor, array($this, 'handleEvent')); }
/** * Start the server */ public function bind() { $err = $errno = 0; $this->flashPolicyFile = str_replace('to-ports="*', 'to-ports="' . $this->uri->getPort() ?: 80, $this->flashPolicyFile); $serverSocket = stream_socket_server($this->uri->toString(), $errno, $err, STREAM_SERVER_BIND | STREAM_SERVER_LISTEN, $this->context); $this->logger->notice(sprintf("phpws listening on %s", $this->uri->toString())); if ($serverSocket == false) { $this->logger->err("Error: {$err}"); return; } $timeOut =& $this->purgeUserTimeOut; $sockets = $this->streams; $that = $this; $logger = $this->logger; $this->loop->addReadStream($serverSocket, function ($serverSocket) use($that, $logger, $sockets) { $newSocket = stream_socket_accept($serverSocket); if (false === $newSocket) { return; } stream_set_blocking($newSocket, 0); $client = new WebSocketConnection($newSocket, $that->loop, $logger); $sockets->attach($client); $client->on("handshake", function (Handshake $request) use($that, $client) { $that->emit("handshake", [$client->getTransport(), $request]); }); $client->on("connect", function () use($that, $client, $logger) { $con = $client->getTransport(); $that->getConnections()->attach($con); $that->emit("connect", ["client" => $con]); }); $client->on("message", function ($message) use($that, $client, $logger) { $connection = $client->getTransport(); $that->emit("message", ["client" => $connection, "message" => $message]); }); $client->on("close", function () use($that, $client, $logger, &$sockets, $client) { $sockets->detach($client); $connection = $client->getTransport(); if ($connection) { $that->getConnections()->detach($connection); $that->emit("disconnect", ["client" => $connection]); } }); $client->on("flashXmlRequest", function () use($that, $client) { $client->getTransport()->sendString($that->flashPolicyFile); $client->close(); }); }); $this->loop->addPeriodicTimer(5, function () use($timeOut, $sockets, $that) { # Lets send some pings foreach ($that->getConnections() as $c) { if ($c instanceof WebSocketTransportHybi) { $c->sendFrame(WebSocketFrame::create(WebSocketOpcode::PING_FRAME)); } } $currentTime = time(); if ($timeOut == null) { return; } foreach ($sockets as $s) { if ($currentTime - $s->getLastChanged() > $timeOut) { $s->close(); } } }); }