Example #1
0
 /**
  * Constructs a new socket.
  *
  * @param  string  $address  Address to make the connection on.
  * @param  string  $options  Connection options
  *
  * @return  void
  */
 public function __construct($address, $options = [])
 {
     parent::__construct();
     $defaults = ['port' => null, 'domain' => AF_INET, 'type' => SOCK_STREAM, 'protocol' => SOL_TCP];
     $options += $defaults;
     $this->_address = $address;
     $this->_options = $options;
     /**
      * TODO
      *
      * Shorten this entire loop.
      */
     $this->_idle = new Process(function ($processor) {
         if (XPSPL_DEBUG) {
             logger(XPSPL_LOG)->debug('Entering socket wait loop');
         }
         $idle = $processor->get_routine()->get_idles_available();
         // 30 second default wait
         $time = 30;
         $utime = 0;
         // Determine if another function has requested to execute in x
         // amount of time
         if (count($processor->get_routine()->get_signals()) !== 0) {
             // If we have signals to process only poll and continue
             $time = 0;
         } elseif (count($idle) >= 2) {
             $default_wait_time = time() + $this->default_wait_time;
             foreach ($idle as $_idle) {
                 // if ($_idle->get_idle() instanceof Time) {
                 //     // echo $default_wait_time.PHP_EOL;
                 //     // echo $_idle->get_idle()->get_time_until().PHP_EOL;
                 //     // echo $_idle->get_idle()->get_time_until() < $default_wait_time.PHP_EOL;
                 //     // echo $_idle->get_idle()->get_time_until() > $default_wait_time.PHP_EOL;
                 //     // echo $_idle.PHP_EOL;
                 // }
                 // if ($_idle->get_idle() instanceof Time && (
                 //     // $default_wait_time > $_idle->get_idle()->get_time_until())) {
                 //     // $time = round($_idle->get_idle()->convert_length(
                 //     //     $_idle->get_idle()->get_time_left(),
                 //     //     TIME_SECONDS
                 //     // ), 3);
                 //     // if ($time > 0 && $time < 1) {
                 //     //     $utime = $time * 1000;
                 //     //     $time = 0;
                 //     // }
                 //     // echo $time.PHP_EOL;
                 //     // break;
                 // }
             }
         }
         // establish sockets
         $re = [$this->_connection->get_resource()];
         $wr = $ex = [];
         foreach ($this->_clients as $_k => $_c) {
             $_resource = $_c->get_resource();
             // test if socket is still connected
             // send disconnect if disconnect detected
             if ($_c->is_connected() === false) {
                 xp_emit(new SIG_Disconnect($_c));
                 unset($this->_clients[$_k]);
                 continue;
             } else {
                 $re[] = $_resource;
                 $ex[] = $_resource;
             }
         }
         $count = socket_select($re, $wr, $ex, $time, $utime);
         if ($count === false) {
             logger(XPSPL_LOG)->debug('Socket wait loop ended PROBLEM');
             return false;
         } elseif ($count == 0) {
             if (XPSPL_DEBUG) {
                 logger(XPSPL_LOG)->debug('Socket wait loop ended no connection changes');
             }
             return true;
         }
         if (XPSPL_DEBUG) {
             logger(XPSPL_LOG)->debug('Socket wait loop ended connection changes detected');
         }
         // Check Read
         if (count($re) !== 0) {
             foreach ($re as $_r) {
                 if (XPSPL_DEBUG) {
                     logger(XPSPL_LOG)->debug(sprintf('Connection Read %s', strval(intval($_r))));
                 }
                 $id = intval($_r);
                 if (!isset($this->_clients[$id])) {
                     $client = new Client($_r);
                     $id = intval($client->get_resource());
                     xp_emit(new SIG_Connect($this, $client));
                     $this->_clients[$id] = $client;
                     if (XPSPL_DEBUG) {
                         logger(XPSPL_LOG)->debug(sprintf('Added Connection %s', strval(intval($id))));
                     }
                 } else {
                     $this->_clients[$id]->_read_buffer();
                     xp_emit(new SIG_Read($this, $this->_clients[$id]));
                 }
             }
         }
         // Check Write
         if (count($wr) !== 0) {
             foreach ($wr as $_write) {
                 if (XPSPL_DEBUG) {
                     logger(XPSPL_LOG)->debug(sprintf('Connection Write %s', strval($_write)));
                 }
                 $processor->get_routine()->add_signal(new SIG_Write($this, $this->_clients[intval($_write)]));
             }
         }
         // Errors
         if (count($ex) !== 0) {
             foreach ($ex as $_excep) {
                 if (XPSPL_DEBUG) {
                     logger(XPSPL_LOG)->debug(sprintf('Connection Exception %s', strval($_excep)));
                 }
                 $this->_clients[intval($_excep)]->error = socket_last_error($_excep);
                 $this->_clients[intval($_excep)]->error_str = socket_strerror($_excep);
                 $processor->get_routine()->add_signal(new SIG_Error($this, $this->_clients[intval($_excep)]));
             }
         }
     });
     $this->on_disconnect(xp_priority(PHP_INT_MAX, '\\network\\system_disconnect'));
     // After processing read clean the buffer
     xp_after(new SIG_Read($this), xp_low_priority('\\network\\clean_buffer'));
     // Emit this has started
     xp_emit($this);
 }