示例#1
0
文件: socket.php 项目: prggmr/xpspl
 /**
  * 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);
 }
示例#2
0
文件: before.php 项目: prggmr/xpspl
<?php

/**
 * Copyright 2010-12 Nickolas Whiting. All rights reserved.
 * Use of this source code is governed by the Apache 2 license
 * that can be found in the LICENSE file.
 */
require_once dirname(realpath(__FILE__)) . '/../__init__.php';
xp_import('unittest');
unittest\test(function ($test) {
    $foo = XP_SIG('foo');
    xp_signal($foo, function () {
    });
    xp_before($foo, function ($foo) {
        $foo->foo = 'foo';
    });
    xp_emit($foo);
    $test->equal($foo->foo, 'foo');
}, 'API Before function');
示例#3
0
 /**
  * Send the signal to disconnect this socket.
  *
  * @param  integer  $how
  *
  * @return  event\Disconnect
  */
 public function disconnect()
 {
     return xp_emit(new SIG_Disconnect(null, $this));
 }
示例#4
0
<?php

ini_set('memory_limit', '10G');
xp_set_signal_history(true);
$sig = XP_SIG('foo');
$time = time();
// Emit a few foo objects
for ($i = 0; $i < 10000000; $i++) {
    xp_emit($sig);
}
$end = time();
$emitted = 0;
foreach (xp_signal_history() as $_node) {
    if ($_node[0]->compare($sig)) {
        $emitted++;
    }
}
echo 'Emitted ' . $emitted . ' signals in ' . ($end - $time) . ' seconds' . PHP_EOL;
echo 'Rate of ' . $emitted / ($end - $time);
示例#5
0
<?php

/**
 * This example demonstrates emitting signals based on network input and analysing
 * the emitted signals from the network to detect a wedding.
 *
 * This allows for recieving input from any input source.
 */
xp_import('network');
$server = network\connect('0.0.0.0', ['port' => 8000]);
$server->on_read(function ($signal) {
    $read = trim($signal->socket->read());
    if ($read == null) {
        return false;
    }
    xp_emit(XP_SIG($read));
});
// Once a bride, groom and bell signals are emitted we emit the wedding.
$wedding = xp_complex_sig(function ($signal) {
    if (!isset($this->reset) || $this->reset) {
        $this->reset = false;
        $this->bride = false;
        $this->groom = false;
        $this->bells = false;
    }
    switch (true) {
        case $signal->compare(XP_SIG('groom')):
            $this->groom = true;
            break;
        case $signal->compare(XP_SIG('bride')):
            $this->bride = true;
示例#6
0
xp_import('network');
$ops = 0;
$thread = xp_threaded_process(function () {
    $start_time = 0;
    $this->operations = 0;
    $sig = XP_SIG('a');
    do {
        echo $ops;
        xp_emit($sig);
        $this->operations++;
        $ops = $this->operations / (microtime(true) - $start_time);
    } while (true);
});
$ops_sig = xp_signal(XP_SIG('op'), xp_exhaust(null, $thread));
xp_emit(XP_SIG('op'));
// $server = network\connect('0.0.0.0', ['port'=>8000]);
// $server->on_connect(xp_null_exhaust(function($server) use ($ops){
// 	$server->socket->write($ops);
// 	$server->socket->disconnect();
// }));
// $server =
// $iterations = 1000000;
// $start = microtime(true);
// for ($i=0;$i<$iterations;$i++) {}
// $end = microtime(true);
// $loop_time = $end - $start;
// $sig = XP_SIG(null);
// $start = microtime(true);
// for ($i=0;$i<$iterations;$i++) {
// 	xp_emit($sig);
示例#7
0
<?php

// Handle Foo
xp_signal(XP_SIG('foo'), function ($signal) {
    echo $signal->bar;
});
// When foo is emitted insert bar into the event
xp_before(XP_SIG('foo'), function ($signal) {
    echo "I RAN" . PHP_EOL;
    $signal->bar = 'foo';
});
xp_before(XP_SIG('foo'), xp_high_priority(function ($signal) {
    echo "I RAN BEFORE" . PHP_EOL;
}));
// After foo is emitted unset bar in the event
xp_after(XP_SIG('foo'), function ($signal) {
    unset($signal->bar);
});
$signal = xp_emit(XP_SIG('foo'));
var_dump(isset($signal->bar));
示例#8
0
文件: threads.php 项目: prggmr/xpspl
<?php

$max_threads = 16 - 1;
class My_Thread extends \XPSPL\Process
{
    public function execute($signal, $thread)
    {
        while (true) {
            var_dump($thread);
        }
    }
}
for ($i = 0; $i < $max_threads; $i++) {
    xp_signal(XP_SIG('test' . $i), xp_threaded_process(new My_Thread()));
}
for ($i = 0; $i < $max_threads; $i++) {
    xp_emit(XP_SIG('test' . $i));
}
示例#9
0
 /**
  * Processes any files awaiting to upload and attempts to begin the upload
  * transfer.
  *
  * @todo  Add an emit for failure to connect, incorrect file.
  *
  * @return  void
  */
 protected function _init_transfers()
 {
     foreach ($this->_files as $_k => $_file) {
         if (!$_file instanceof File) {
             continue;
         }
         if ($this->_options['secure']) {
             $connection = ftp_ssl_connect($this->_options['hostname'], $this->_options['port'], $this->_options['timeout']);
         } else {
             $connection = ftp_connect($this->_options['hostname'], $this->_options['port'], $this->_options['timeout']);
         }
         if (false === $connection) {
             break;
         }
         $login = ftp_login($connection, $this->_options['username'], $this->_options['password']);
         if ($login === false) {
             $this->_sig_failure->set_upload($_file);
             xp_emit($this->_sig_failure, new SIG_Failure($_file));
             ftp_close($connection);
             break;
         }
         if (!file_exists($_file->get_full_path())) {
             xp_emit($this->_sig_failure, new SIG_Failure($_file));
         } else {
             $transfer = ftp_nb_put($connection, $_file->get_name(), $_file->get_full_path(), $_file->get_transfer_mode());
             if ($transfer === FTP_MOREDATA) {
                 $this->_uploading[] = [$connection, $_file];
             } else {
                 if ($transfer == FTP_FINISHED) {
                     $this->_sig_complete->set_upload($_file);
                     xp_emit($this->_sig_complete);
                     // Close the FTP connection to that file
                     ftp_close($connection);
                     $this->_uploaded[] = $_file;
                 } else {
                     $this->_sig_failure->set_upload($_file);
                     xp_emit($this->_sig_failure);
                     // Close the FTP connection to that file
                     ftp_close($connection);
                 }
             }
         }
         unset($this->_files[$_k]);
     }
 }