/**
  * 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);
     });
 }
예제 #2
0
 /**
  * @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;
 }
예제 #3
0
 /**
  * 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;
 }
예제 #4
0
 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;
     }
 }
예제 #5
0
파일: React.php 프로젝트: walkor/workerman
 /**
  * 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;
 }
예제 #6
0
 /**
  * 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;
     });
 }
예제 #7
0
 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);
 }
예제 #8
0
 protected function register()
 {
     if ($this->active) {
         return;
     }
     $this->active = true;
     $this->loop->addReadStream($this->fd, [$this, 'handleEvent']);
 }
예제 #9
0
 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;
     }
 }
예제 #10
0
파일: Shell.php 프로젝트: fieg/shell
 /**
  * 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();
 }
예제 #11
0
 /** @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);
 }
예제 #12
0
 /**
  * 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);
     });
 }
예제 #13
0
파일: Loop.php 프로젝트: daverandom/loopio
 /**
  * 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;
 }
예제 #14
0
파일: nsqphp.php 프로젝트: KOGI/nsqphp
 /**
  * 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;
 }
예제 #15
0
 public function attachReadListener()
 {
     $this->loop->addReadStream($this->fileDescriptor, array($this, 'handleEvent'));
 }
예제 #16
0
 /**
  * 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();
             }
         }
     });
 }