{language}
  • Examples
  • FAQ
  • Documentation
  • Issues
  • Team
  • Contribute
  • Publications
  • Introduction

    Achtung! Documentation is under active construction! Consider making a contribution.

    PHPDaemon — asynchronous framework You can built very fast applications, web-services and more on top of it. Out-of-box it provides a wide range of network servers such as FastCGI, HTTP, CGI, FlashPolicy, Telnet, WebSocket; clients like MySQL, Redis, MongoDB, PostgreSQL, Memcached, IRC, XMPP, and others. Network programming became very simple. Middle developer can implement, e.g., full-featured IRC-bot in a hour.

    Usage of this documentation Introduction

    As you may see, whole documentation is placed on one page, so feel free to use standard search within the page (hotkey is Ctrl + F or Cmd + F)

    Installation

    Requirements Installation

    It's recommended to install these non-mandatory modules:

    Source code Installation

    You may clone the repository $ git clone https://github.com/kakserpom/phpdaemon.git

    Or download current version as an archive $ wget https://github.com/kakserpom/phpdaemon/archive/master.zip

    Then install mandatory PHP modules $ pecl install event eio inotify

    Composer Installation

    Add a section into yours composer.json

    "require" : {
        "kakserpom/phpdaemon" : "dev-master"
    }

    Futhermore information about the package is located at packagist.org.

    CentOS/RedHat Installation

    First of all you should install related utilities. $ sudo yum install -y git gcc openssl-devel libevent

    To install latest PHP. you should add the Remi and the Epel repositories, because standard package may contain outdated version.

    For RHEL/CentOS 6.4-6.0 32 Bit.

    sudo rpm -Uvh http://download.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm
    sudo rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-6.rpm

    For RHEL/CentOS 6.4-6.0 64 Bit.

    sudo rpm -Uvh http://download.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
    sudo rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-6.rpm
    #Installing PHP.
    sudo yum --enablerepo=remi,remi-test install -y php-cli php-devel php-pear php-process
    
    #Then installing PHP modules.
    sudo -i
    pecl install event eio
    
    #Modules `event` and `eio` require module `sockets`.
    #In RedHat/CentOS, configuration files load up in alphabetic order, so name them `z-event.ini` and `z-eio.ini` accordingly.  
    echo "extension=event.so" > /etc/php.d/z-event.ini
    echo "extension=eio.so" > /etc/php.d/z-eio.ini
    
    exit #out of sudo

    Define date.timezone in /etc/php.ini.

    #Prepare a folder for PHPDaemon.
    sudo mkdir /opt/phpdaemon
    sudo chown [your user]:[your group] /opt/phpdaemon
    cd /opt/phpdaemon
    
    #Installing PHPDaemon.  
    cd /opt/phpdaemon
    git clone https://github.com/kakserpom/phpdaemon.git ./
    
    #Copying configuration file from sample:
    cp /opt/phpdaemon/conf/phpd.conf.example /opt/phpdaemon/conf/phpd.conf
    
    #Creating a link for phpd
    ln -s /opt/phpdaemon/bin/phpd /usr/bin/phpd

    Then run the thing:
    sudo phpd start --verbose-tty=1

    Option --verbose-tty=1 turns on logging into STDOUT

    If you see something like this:

    [PHPD] Loaded config file: '/opt/phpdaemon/conf/phpd.conf'
    [PHPD] Loaded config file: 'conf/conf.d/ExampleJabberBot.conf'
    [PHPD] Loaded config file: 'conf/conf.d/FastCGI.conf'
    [PHPD] Loaded config file: 'conf/conf.d/FlashpolicyServer.conf'
    [PHPD] Loaded config file: 'conf/conf.d/HTTPServer.conf'
    [PHPD] Loaded config file: 'conf/conf.d/IdentServer.conf'
    [PHPD] Loaded config file: 'conf/conf.d/SSL-sample.conf'
    [PHPD] Loaded config file: 'conf/conf.d/WebSocketServer.conf'

    Congratulatious! PHPDaemon is working!

    Ubuntu Installation

    #First of all you should install related utilities.
    sudo -i  
    apt-get install gcc make libcurl4-openssl-dev libevent-dev git libevent
    
    #Installing PHP 5.5.  
    apt-get install php5-cli php5-dev php-pear
    
    #Then install PHP modules.
    pecl install event eio  
    echo "extension=event.so" > /etc/php5/mods-available/event.ini  
    echo "extension=eio.so" > /etc/php5/mods-available/eio.ini
    
    #Creating links
    ln -s /etc/php5/mods-available/event.ini /etc/php5/cli/conf.d/event.ini 
    ln -s /etc/php5/mods-available/eio.ini /etc/php5/cli/conf.d/eio.ini
    
    #Prepare a folder for PHPDaemon.  
    mkdir /opt/phpdaemon
    chown [your user]:[your group] /opt/phpdaemon
    exit #exiting root user
    
    #Installing PHPDaemon.  
    cd /opt/phpdaemon
    git clone https://github.com/kakserpom/phpdaemon.git ./
    
    #Creating configuration file from sample.
    cp /opt/phpdaemon/conf/phpd.conf.example /opt/phpdaemon/conf/phpd.conf
    
    #Let's create an alias of `phpd` for convenience.  
    alias phpd='/opt/phpdaemon/bin/phpd'
    
    #Local alias of sudo:  
    alias sudo='sudo '

    Then run the thing:
    sudo phpd start --verbose-tty=1

    Option --verbose-tty=1 turns on logging into STDOUT

    If you see something like this:

    [PHPD] Loaded config file: '/opt/phpdaemon/conf/phpd.conf'
    [PHPD] Loaded config file: 'conf/conf.d/ExampleJabberBot.conf'
    [PHPD] Loaded config file: 'conf/conf.d/FastCGI.conf'
    [PHPD] Loaded config file: 'conf/conf.d/FlashpolicyServer.conf'
    [PHPD] Loaded config file: 'conf/conf.d/HTTPServer.conf'
    [PHPD] Loaded config file: 'conf/conf.d/IdentServer.conf'
    [PHPD] Loaded config file: 'conf/conf.d/SSL-sample.conf'
    [PHPD] Loaded config file: 'conf/conf.d/WebSocketServer.conf'

    Congratulatious! PHPDaemon is working!

    Let's make the aliases permanent:

    echo "alias phpd='/opt/phpdaemon/bin/phpd'" >> ~/.bashrc
    echo "alias sudo='sudo /opt/phpdaemon/bin/phpd'" >> ~/.bashrc

    Gentoo Installation

    You may install PHPDaemon with layman overlay.

    Add this reference into the overlays section in layman.cfg file: https://github.com/lexa-uw/layman-phpdaemon/blob/master/layman.xml

    It should like that:

    overlays  : http://www.gentoo.org/proj/en/overlays/repositories.xml
                https://github.com/lexa-uw/layman-phpdaemon/blob/master/layman.xml

    Execute the following commands:

    sudo layman -L
    sudo layman -a phpdaemon
    sudo emerge www-servers/phpdaemon

    For example, below command install phpdaemon by version 0.4.1, 1.0_beta2 and weekly release.

    $ sudo emerge "=www-servers/phpdaemon-0.4.1" "=www-servers/phpdaemon-1.0_beta2" "www-servers/phpdaemon"
    These are the packages that would be merged, in order:
    
    Calculating dependencies... done!
    [ebuild   R   ~] www-servers/phpdaemon-0.4.1:0.4::phpdaemon  USE="libevent -examples -runkit" 0 kB
    [ebuild   R   ~] www-servers/phpdaemon-1.0_beta2:1.0::phpdaemon  USE="eio event -runkit" 0 kB
    [ebuild   R   ~] www-servers/phpdaemon-20130907:weekly::phpdaemon  USE="eio event -runkit" 0 kB
    ...

    After installation you can use "eselect phpdaemon set" tool for set up symlink for /usr/bin/phpd

    $ sudo eselect phpdaemon list
    Available phpdaemon targets:
      [1]   phpd0.4
      [2]   phpd1.0
      [3]   phpdweekly
    $ sudo eselect phpdaemon set 3
    $ sudo eselect phpdaemon show
    Current phpdaemon:
      weekly

    Add phpdaemon to autoload:

    $ rc-update add phpd default
     * service phpd added to runlevel default

    Add sepatare init.d scripts for different versions:

    $ ln -s /etc/init.d/phpd /etc/init.d/phpd-0.4
    $ ln -s /etc/init.d/phpd /etc/init.d/phpd-1.0
    $ ln -s /etc/init.d/phpd /etc/init.d/phpd-weekly

    And add phpd-1.0 to autoload:

    $ rc-update add phpd-1.0 default
     * service phpd added to runlevel default

    Basics

    PHPDaemon represents one master process with multiple workflows.

    Application, depending on the load, is initialized to one or more workflows. In the second case, the request will be given one free workflow.

    Mechanism of interaction between rebochimi processes is not provided, so for synchronization applications in different processes, you can use third-party software, such as Redis. It is also possible to specify the application option limit-instances N; to limit the number of copies of the application in all operating processes.

    The executable file is located in dirktor ./bin/phpd. You can create your own executable file, as shown in the example ./bin/sampleapp. Before starting the daemon checks for a variable $configFile, using it to load the configuration.

    Псевдотипы Basics

    Pseudotype url @TODO

    Control

    $ phpd start Launch daemon
    $ phpd stop Stop daemon
    SYSCTL: SIGTERM, SIGQUIT
    $ phpd hardstop Force-stop daemon
    SYSCTL: SIGINT, SIGKILL
    $ phpd update Update configuration
    SYSCTL: SIGHUP
    $ phpd reload Graceful restart of all work processes
    SYSCTL: SIGUSR2
    $ phpd reopenlog Reopen journal
    SYSCTL: SIGUSR1
    $ phpd restart Graceful daemon restart
    $ phpd hardrestart Force-restart daemon
    $ phpd status Show daemon status
    $ phpd fullstatus Show detailed information about daemon
    $ phpd configtest Show global options. The value in parentheses is the default value.
    $ phpd log [-n K] Log output in real time using the command tail -f. With parameter -n K print last K lines. Or use -n +K to output starting with line K.
    $ phpd runworker Starting a workflow without a master process. Used for debugging.

    Examples

    Examples

    App resolver

    When receiving requests, the daemon must first determine which application it should pass processing to. This is done using the getRequestRoute method in the AppResolver class.

    You can define your own handler - an example can be found in ./conf/AppResolver.php [https://github.com/kakserpom/phpdaemon/blob/master/conf/AppResolver.php].

    The getRequestRoute method has two arguments:

    The return value of this method can be:

    Don't forget to specify in config the path to your AppResolver, for example path './conf/AppResolver.php';.

    In the settings of the server receiving the requests, you can use the responder option to specify the default name of the application to which the request will be passed if getRequestRoute returns null.

    Configuration

    Data types Configuration

    Most phpdaemon options are described by their data types, allowing you to specify values in an extended format.

    This is used to specify an amount of data. It can be written either as a whole number or as a whole number with a suffix.

    Format: integer [bBkKmMgG]?

    Suffix Factor Example Value
    b, B 1 1b 1
    k 1000 1k 1000
    K 1024 1K 1024
    m 1000 * 1000 1m 1000000
    M 1024 * 1024 1M 1048576
    g 1000 * 1000 * 1000 1g 1000000000
    G 1024 * 1024 * 1024 1G 1073741824

    This is used to specify a number of seconds. The number can be floating point using the decimal separator "." only.

    Format: float [smhd]? or (float [smhd])+

    Suffix Factor Example Value
    s 1 1s 1
    m 60 1m 60
    h 60 * 60 2h 12s 7212
    d 60 * 60 * 24 1d 15m 32s 87332

    Number Data types Configuration

    This is used to specify numbers.

    Format: integer [kKmMgG]?

    Suffix Factor Example Value
    k, K 1000 1k 1000
    m, M 1000 * 1000 1M 1000000
    g, G 1000 * 1000 * 1000 1g 1000000000

    Global Options Configuration

    There are two ways to set options:

    1. Configuration file ./conf/phpd.conf;
    2. Command line parameters, e.g. --max-workers=1.

    The command line parameters have higher priority.

    Configuration file Global Options Configuration

    Options are specified in the following format: option-name; or option-name value;

    option-name is case insensitive, hyphens "-" are ignored. Thus, the following spellings are equivalent:

    The value may not exist at all, which equals to bool(true), or may be written in the following ways:

    To write an array, the space " " or comma "," separator is used. You can use both separators within the same value.

    Example option var_dump output
    var-name; bool(true)
    var-name null; NULL
    var-name true; bool(true)
    var-name false; bool(false)
    var-name 0; int(0)
    var-name 1; int(1)
    var-name 3.14; float(3.14)
    var-name "3.14"; string(4) "3.14"
    var-name "example. long line, second example"; string(34) "example. long line, second example"
    var-name example. long line, second example; array(5) {
        [0]=>
        string(8) "example."
        [1]=>
        string(4) "long"
        [2]=>
        string(4) "line"
        [3]=>
        string(6) "second"
        [4]=>
        string(7) "example"
    }
    var-name 1, 'a' null 3.14 'a word or two'; array(5) {
        [0]=>
        int(1)
        [1]=>
        string(1) "a"
        [2]=>
        NULL
        [3]=>
        float(3.14)
        [4]=>
        string(13) "a word or two"
    }

    The available global options for the daemon are listed below in the following format: option-name (data-type = default-value);

    Graceful restart of worker processes Global Options Configuration

    Main paths Global Options Configuration

    Related to the master process Global Options Configuration

    Requests Global Options Configuration

    Worker processes Global Options Configuration

    Logging and debugging Global Options Configuration

    POSIX I/O subsystem Global Options Configuration

    Applications Configuration

    Development

    Application Development

    Appendix B is a subclass phpDaemon AppInstance, to create a new application, you must create a file applications / [name] .php and call it class Example extends AppInstance. Then, the kernel will call methods in response to which the application must perform the required operations:

    init() - initialize the application. The application needs to maintain the required dependencies and prepare for the launch. onReady() - it means that the working process in which the application is ready to run processing. onShutdown() - the completion of the application. beginRequest(Request $ req, AppInstance $ upstream) - sought a new request object to the application. The method can return false, this means that the application is refused (or not able) to handle requests. After calling this method, the request object enters the queue and invoked iteratively. The class is declared as class ExampleRequest extends Request. Methods:

    init() - is invoked only once when creating the request object. run() - called the dispatcher queue to ter long as it will be returned code 1 or terminate method is called (). terminate() - it should not be rebooted. Method interrupts and terminates the request. sleep($seconds) - the time in seconds after which you want to return to the query. wakeup() - interrupt sleep. onAbort() - request a reset event is called if the client fell off. header($header) - set the HTTP-response header. out($str) - to write to the output stream line. combinedOut($str) - write a string to the output stream containing both headers and body. stdin($str) - processor input stream of the request. finish($status) - 0 - normal, -1 - abort, -2 - termination chunked() - set Transfer-Encoding: chunked.

    Processing Query Development

    Servers and clients Development

    Debug Development

    Servers

    Servers are responsible for receiving requests and passing them to applications.

    Each server is a class inherited from Network\Server, which in turn is inherited from Network\Pool. The server can be initiated directly in the user application, for example:

    /* ... */
    $this->pool = \PHPDaemon\Servers\FlashPolicy::getInstance([
        'listen' => 'tcp://0.0.0.0:843'
    ]);
    $this->pool->onReady();
    /* ... */

    But do not forget that in this case you should send onReady(), onShutdown() and onConfigUpdated() events.

    In most cases, the server is run by the Pool application of the same name.

    # context for ssl connection (optional)
    TransportContext:myContext {
        tls;
        certFile "/path/to/cert.pem";
        pkFile "/path/to/privkey.pem";
        passphrase "";
        verifyPeer true;
        allowSelfSigned true;
    }
    
    # listening to port 80 and 443
    Pool:HTTPServer {
        listen "tcp://0.0.0.0:80", "tcp://0.0.0.0:443##myContext";
        port 80;
        privileged;
        maxconcurrency 1;
    }

    Server options Servers

    This section lists the options used by all servers.

    HTTP Servers

    The server uses the namespace HTTPRequest.

    This vehicle application provides HTTP server for phpDaemon. Incoming connections will be transferred Websocket WebsocketServer application.

    HTTP is trying to determine the application through AppResolver, be sure to configure it.

    Connection HTTP Servers

    namespace PHPDaemon\Servers\HTTP;
    class Connection extends \PHPDaemon\Network\Connection;
    Constants Connection HTTP Servers
    Methods Connection HTTP Servers

    Pool HTTP Servers

    namespace PHPDaemon\Servers\HTTP;
    class Pool extends \PHPDaemon\Network\Server;
    Options Pool HTTP Servers
    Properties Pool HTTP Servers
    Methods Pool HTTP Servers

    FastCGI Servers

    The server uses the namespace HTTPRequest.

    This vehicle is an application server for FastCGI phpDaemon.

    After configuring phpDaemon you should also use a Web server that supports FastCGI. If you have not made a choice in favor of one of them, we recommend to NGINX.

    The web server can transmit the FastCGI-server option APPNAME, which contains the name of the application that should handle the request. If not passed, FastCGI-server will try to determine this through AppResolver.

    Configuration example NGINX:

    location /Example/ {
        fastcgi_pass unix:/tmp/phpdaemon.fcgi.sock;
        fastcgi_param APPNAME Example;
        include fastcgi_params;
    }

    Connection FastCGI Servers

    namespace PHPDaemon\Servers\FastCGI;
    class Connection extends \PHPDaemon\Network\Connection;
    Constants Connection FastCGI Servers
    Properties Connection FastCGI Servers
    Methods Connection FastCGI Servers

    Pool FastCGI Servers

    namespace PHPDaemon\Servers\FastCGI;
    class Pool extends \PHPDaemon\Network\Server;
    Options Pool FastCGI Servers
    Properties Pool FastCGI Servers
    Methods Pool FastCGI Servers

    DebugConsole Servers

    This vehicle application provides interactive debugging console phpDaemon.

    # telnet 127.0.0.1 8818
    Trying 127.0.0.1...
    Connected to 127.0.0.1.
    Escape character is '^]'.
    Welcome! DebugConsole for phpDaemon.
    
    login secret
    OK.
    eval echo 123;
    123

    Connection DebugConsole Servers

    namespace PHPDaemon\Servers\DebugConsole;
    class Connection extends \PHPDaemon\Network\Connection;
    Properties Connection DebugConsole Servers
    Methods Connection DebugConsole Servers

    Pool DebugConsole Servers

    namespace PHPDaemon\Servers\DebugConsole;
    class Pool extends \PHPDaemon\Network\Server;
    Options Pool DebugConsole Servers

    FlashPolicy Servers

    This simple application provides Flashpolicy server phpDaemon.

    This application should be included in case you want to connect to a server via Flash.

    Connection FlashPolicy Servers

    namespace PHPDaemon\Servers\FlashPolicy;
    class Connection extends \PHPDaemon\Network\Connection;
    Methods Connection FlashPolicy Servers

    Pool FlashPolicy Servers

    namespace PHPDaemon\Servers\FlashPolicy;
    class Pool extends \PHPDaemon\Network\Server;
    Options Pool FlashPolicy Servers
    Properties Pool FlashPolicy Servers
    Methods Pool FlashPolicy Servers

    Ident Servers

    Connection Ident Servers

    namespace PHPDaemon\Servers\Ident;
    class Connection extends \PHPDaemon\Network\Connection;

    Pool Ident Servers

    namespace PHPDaemon\Servers\Ident;
    class Pool extends \PHPDaemon\Network\Server;
    Options Pool Ident Servers
    Methods Pool Ident Servers

    IRCBouncer Servers

    Connection IRCBouncer Servers

    namespace PHPDaemon\Servers\IRCBouncer;
    class Connection extends \PHPDaemon\Network\Connection;
    Properties Connection IRCBouncer Servers
    Methods Connection IRCBouncer Servers

    Pool IRCBouncer Servers

    namespace PHPDaemon\Servers\IRCBouncer;
    class Pool extends \PHPDaemon\Network\Server;
    Options Pool IRCBouncer Servers
    Properties Pool IRCBouncer Servers
    Methods Pool IRCBouncer Servers

    Lock Servers

    It requires refactoring

    Connection Lock Servers

    namespace PHPDaemon\Servers\Lock;
    class Connection extends \PHPDaemon\Network\Connection;
    Properties Connection Lock Servers
    Methods Connection Lock Servers

    Pool Lock Servers

    namespace PHPDaemon\Servers\Lock;
    class Pool extends \PHPDaemon\Network\Server;
    Options Pool Lock Servers
    Properties Pool Lock Servers

    Socks Servers

    Connection Socks Servers

    namespace PHPDaemon\Servers\Socks;
    class Connection extends \PHPDaemon\Network\Connection;
    Constants Connection Socks Servers
    Methods Connection Socks Servers

    SlaveConnection Socks Servers

    namespace PHPDaemon\Servers\Socks;
    class SlaveConnection extends \PHPDaemon\Servers\Socks\Connection;
    Methods SlaveConnection Socks Servers

    Pool Socks Servers

    namespace PHPDaemon\Servers\Socks;
    class Pool extends \PHPDaemon\Network\Server;
    Options Pool Socks Servers

    WebSocket Servers

    The server uses the namespace HTTPRequest.

    This vehicle is an application WebSocket server phpDaemon.

    Your application must obtain a reference to an instance and call WebSocketServer addRoute() to add their own ways. Callback-way function must return a new instance of your class that inherits from WebSocketRoute determines onFrame method. Inside the method onFrame we can contact $this->client->sendFrame() to send packets to the client.

    Connection WebSocket Servers

    namespace PHPDaemon\Servers\WebSocket;
    class Connection extends \PHPDaemon\Network\Connection;
    Constants Connection WebSocket Servers
    Properties Connection WebSocket Servers
    Methods Connection WebSocket Servers

    Pool WebSocket Servers

    namespace PHPDaemon\Servers\WebSocket;
    class Pool extends \PHPDaemon\Network\Server;
    Options Pool WebSocket Servers
    Constants Pool WebSocket Servers
    Properties Pool WebSocket Servers
    Methods Pool WebSocket Servers

    Clients

    At the heart of all customers is the namespace the Network, the study of which will give a greater understanding of customer opportunities and networking daemon as a whole.

    Basics Clients

    Clients options Basics Clients

    Asterisk Clients

    namespace PHPDaemon\Clients\Asterisk;

    Раздел устарел!

    Asterisk - is an open-source PBX. AMI - Asterisk's software interface (API) for system management, which allows developers to send commands to the server, read the results of their execution, as well as receive notifications about events in real time. The Asterisk client provides a high-level interface to AMI, allowing developers to control the Asterisk server from applications.

    The documentation of the client is based on the material in the book Asterisk: будущее телефонии.

    Usage Asterisk Clients

    @TODO it's from the wiki, check it out.

    Before sending commands and receiving events from the server, you need to get the connection session(s) in your application. In your application you receive the AsteriskDriver object through:

    $this->pbxDriver = Daemon::$appResolver->getInstanceByAppName('AsteriskDriver');
    Connection Usage Asterisk Clients

    Next you get the AsteriskDriverSession object through:

    $session = $this->pbxDriver->getConnection();
    // или
    foreach($this->pbxConnections as $addr => $conn) {
        $session = $this->pbxDriver->getConnection($addr);
        // do something...
    }

    Add (composition) to it the current connection context by means of:

    $session->context = $this;

    On connect:

    $session->onConnected(function(SocketSession $session, $status) {
        // your code, depending on the connection
    });

    On disconnect:

    $session->onFinish(function(SocketSession $session) {
        // maybe run reconnect interval
    });

    Suppose that you have multiple Asterisk servers from which you want to receive events and to which you want to send action commands. You also want to track down connection failure and perform a reconnect. See below for an example on how to reconnect.

    A little bit about the I/O format Usage Asterisk Clients

    Although AMI is a string-based protocol, the driver works with associative arrays during I/O. When an action or event is replied to, all headers and their values are case-sensitive if the value does not contain case-sensitive information, such as the name of the pirate.

    Sending commands and receiving a response Usage Asterisk Clients

    To send a command and receive a response, you can use either the helper method, which has a detailed explanation in the Asterisk documentation, or the universal Connection::action method.

    In any case, for each command you define a callback function to which the connection session object and an associative header-value pair array will be passed.

    The client correctly handles that the order of response packets is not defined and correctly assembles the response packets.

    $session->getSipPeers(function(SocketSession $session, array $packet) {
        // $session->addr contain the connection address
        // $session->context contains the call context (if installed)
        // $packet - is an array of response header-value pairs.
        // do something
    })
    // or
    $session->getConfig('chan_dahdi.conf', array($this, 'doSomething'));
    public function doSomething(SocketSession $session, array $packet) {
    
    }
    // or
    $session->action('Ping', function(SocketSession $session, array $packet) {
        if($packet['response'] == 'success' && $packet['ping'] == 'pong') {
            // successfully played ping-pong
        }
    });
    // or
    // $channel contains the channel from the event
    $session->redirect(array(
        'Channel' => $channel,
        'Context' => 'internal',
        'Exten' => '116',
        'Priority' => 1
    ), function(SocketSession $session, array $packet) {
      // find out whether it was successful or not from the server response contained in the $packet associative array
    });
    Receiving server events Usage Asterisk Clients

    The callback function when an event occurs in this connection is defined once and passed to the onEvent() method.

    $session->onEvent(array($this, 'onPbxEvent'));

    When several worker are launched, you can use the lock table to avoid that the channel events (which are characterized by a unique identifier (uniqueid) of the channel) are multiple of the number of workers. Here is an example, when MongoDB collection is used as a lock table, which allows to put a unique index on a document:

    $session->onEvent(array($this, 'onPbxEvent'));
    // db.events.ensureIndex({"event": 1, "addr": 1}, {unique: true});
    public function onPbxEvent(SocketSession $session, array $event) {
        if(method_exists('Foo_PbxEventDispatcher', "{$event['event']}Handler")) {
            $handler = "{$event['event']}Handler";
            if(isset($event['uniqueid']) || isset($event['uniqueid1'])) {
                $appInstance = $this;
                $this->db->events->insert(
                    array(
                            'ts' => microtime(true),
                            'event' => $event,
                            'addr' => $session->addr
                    ),
                    function($result) use ($appInstance, $session, $event) {
                        if($result['err'] === null) {
                            $handler = "{$event['event']}Handler";
                            Foo_PbxEventDispatcher::$handler($appInstance, $session, $event);
                        }
                    }
                );
            }
            else {
                Foo_PbxEventDispatcher::$handler($this, $session, $event);
            }
        }
    }

    Example on how to reconnect Asterisk Clients

    class Foo extends AppInstance {
        // ...
        public function onInit() {
            // pbxConnections - array of connections
            foreach($this->pbxConnections as $addr => $conn) {
                $pbx_driver_session = $this->pbxDriver->getConnection($addr);
                if($pbx_driver_session instanceof SocketSession) {
                    $pbx_driver_session->context = $this;
                    //$pbx_driver_session->onError(array($this, 'onPbxError'));
                    $pbx_driver_session->onConnected(array($this, 'onPbxConnected'));
                    $pbx_driver_session->onEvent(array($this, 'onPbxEvent'));
                    $pbx_driver_session->onFinish(array($this, 'onPbxFinish'));
                }
                else {
                    $this->runPbxReconnectInterval($pbx_driver_session);
                }
            }
        }
        // ...
        public function onPbxConnected(SocketSession $session, $status) {
            if($status) {
                if($session->context instanceof PbxReconnector) {
                    $session->context->finish();
                }
                // do something...
            }
            else {
                $this->runPbxReconnectInterval($session);
            }
        }
        // ...
        public function onPbxFinish(SocketSession $session) {
            $this->runPbxReconnectInterval($session);
        }
        // ...
        public function runPbxReconnectInterval(SocketSession $session) {
                    if(Daemon::$process->terminated) {
                return;
            }
            foreach ($this->queue as &$r) {
                if($r instanceof PbxReconnector) {
                    if ($r->attrs->addr == $session->addr) {
                        return;
                    }
                }
            }
            $interval = $this->pushRequest(new PbxReconnector($this, $this));
            $interval->attrs->addr = $session->addr;
        }
        // ...
    }
    // ...
    class PbxReconnector extends Request {
            public $interval = 0.3;
    
        public function run() {
            $pbx_driver_session = $this->appInstance->pbxDriver->getConnection($this->attrs->addr);
            if($pbx_driver_session) {
                if($this->appInstance->config->{'pbxreconnectorlogging'}->value) {
                    Daemon::log('Reconnecting to ' . $this->attrs->addr);
                }
                $pbx_driver_session->context = $this;
                $pbx_driver_session->onConnected(array($this->appInstance, 'onPbxConnected'));
                $pbx_driver_session->onFinish(array($this->appInstance, 'onPbxFinish'));
            }
            $this->sleep($this->interval);
        }
    }

    Connection Asterisk Clients

    namespace PHPDaemon\Clients\Asterisk;
    class Connection extends \PHPDaemon\Network\ClientConnection;

    Asterisk Call Manager Connection

    Constants Connection Asterisk Clients
    Properties Connection Asterisk Clients
    Methods Connection Asterisk Clients

    ConnectionFinished Asterisk Clients

    namespace PHPDaemon\Clients\Asterisk;
    class ConnectionFinished extends \PHPDaemon\Exceptions\ConnectionFinished;

    Driver for Asterisk Call Manager/1.1

    Pool Asterisk Clients

    namespace PHPDaemon\Clients\Asterisk;
    class Pool extends \PHPDaemon\Network\Client;

    Class Pool

    Options Pool Asterisk Clients
    Properties Pool Asterisk Clients
    Methods Pool Asterisk Clients

    DNS Clients

    namespace PHPDaemon\Clients\DNS;

    Connection DNS Clients

    namespace PHPDaemon\Clients\DNS;
    class Connection extends \PHPDaemon\Network\ClientConnection;
    Constants Connection DNS Clients
    Properties Connection DNS Clients
    Methods Connection DNS Clients

    Pool DNS Clients

    namespace PHPDaemon\Clients\DNS;
    class Pool extends \PHPDaemon\Network\Client;
    Options Pool DNS Clients
    Properties Pool DNS Clients
    Methods Pool DNS Clients

    Gibson Clients

    namespace PHPDaemon\Clients\Gibson;

    Connection Gibson Clients

    namespace PHPDaemon\Clients\Gibson;
    class Connection extends \PHPDaemon\Network\ClientConnection;
    Constants Connection Gibson Clients
    Properties Connection Gibson Clients
    Methods Connection Gibson Clients

    Pool Gibson Clients

    namespace PHPDaemon\Clients\Gibson;
    class Pool extends \PHPDaemon\Network\Client;
    Options Pool Gibson Clients
    Methods Pool Gibson Clients

    HTTP Clients

    namespace PHPDaemon\Clients\HTTP;

    Designed to perform GET and POST requests to remote hosts.

    The client uses the namespace HTTPRequest.

    Examples HTTP Clients

    Receiving a file google.com/robots.txt GET by request:

    $httpclient = \PHPDaemon\Clients\HTTP\Pool::getInstance();
    
    $httpclient->get('http://www.google.com/robots.txt',
        function ($conn, $success) {
            // response data processing
        }
    );

    A working example of a client is presented in Clients/HTTP/Examples/Simple.php

    Connection HTTP Clients

    namespace PHPDaemon\Clients\HTTP;
    class Connection extends \PHPDaemon\Network\ClientConnection;
    Constants Connection HTTP Clients
    Properties Connection HTTP Clients
    Methods Connection HTTP Clients

    Pool HTTP Clients

    namespace PHPDaemon\Clients\HTTP;
    class Pool extends \PHPDaemon\Network\Client;
    Options Pool HTTP Clients
    Methods Pool HTTP Clients

    -#.method ```php:p.inline.wico[data-link=https://github.com/kakserpom/phpdaemon/blob/master/PHPDaemon/Clients/HTTP/Pool.php#L40] ( url $url, array $params ); ( url $url, callable $resultcb );

       -.n Performs GET-request
       -.n.ti `:hc`$url`
       -.n `:hc`$params`
       -.n `:hc`$resultcb` — `:phc`callback ( Connection $conn, boolean $success )`
    
     -#.method ```php:p.inline.wico[data-link=https://github.com/kakserpom/phpdaemon/blob/master/PHPDaemon/Clients/HTTP/Pool.php#L77]
     ( url $url, array $data, array $params );
     ( url $url, array $data, callable $resultcb );

    ICMP Clients

    namespace PHPDaemon\Clients\ICMP;

    Connection ICMP Clients

    namespace PHPDaemon\Clients\ICMP;
    class Connection extends \PHPDaemon\Network\ClientConnection;
    Methods Connection ICMP Clients

    Pool ICMP Clients

    namespace PHPDaemon\Clients\ICMP;
    class Pool extends \PHPDaemon\Network\Client;
    Methods Pool ICMP Clients

    IRC Clients

    namespace PHPDaemon\Clients\IRC;

    Channel IRC Clients

    namespace PHPDaemon\Clients\IRC;
    class Channel extends \PHPDaemon\Structures\ObjectStorage;
    Properties Channel IRC Clients
    Methods Channel IRC Clients

    ChannelParticipant IRC Clients

    namespace PHPDaemon\Clients\IRC;
    class ChannelParticipant;
    Properties ChannelParticipant IRC Clients
    Methods ChannelParticipant IRC Clients

    Connection IRC Clients

    namespace PHPDaemon\Clients\IRC;
    class Connection extends \PHPDaemon\Network\ClientConnection;
    Properties Connection IRC Clients
    Methods Connection IRC Clients

    Pool IRC Clients

    namespace PHPDaemon\Clients\IRC;
    class Pool extends \PHPDaemon\Network\Client;
    Options Pool IRC Clients
    Properties Pool IRC Clients
    Methods Pool IRC Clients

    Lock Clients

    namespace PHPDaemon\Clients\Lock;

    It requires refactoring

    Connection Lock Clients

    namespace PHPDaemon\Clients\Lock;
    class Connection extends \PHPDaemon\Network\ClientConnection;
    Methods Connection Lock Clients

    Pool Lock Clients

    namespace PHPDaemon\Clients\Lock;
    class Pool extends \PHPDaemon\Network\Client;
    Options Pool Lock Clients
    Methods Pool Lock Clients

    Memcache Clients

    namespace PHPDaemon\Clients\Memcache;

    Connection Memcache Clients

    namespace PHPDaemon\Clients\Memcache;
    class Connection extends \PHPDaemon\Network\ClientConnection;
    Constants Connection Memcache Clients
    Properties Connection Memcache Clients

    Pool Memcache Clients

    namespace PHPDaemon\Clients\Memcache;
    class Pool extends \PHPDaemon\Network\Client;
    Options Pool Memcache Clients
    Methods Pool Memcache Clients

    Mongo Clients

    namespace PHPDaemon\Clients\Mongo;

    Collection Mongo Clients

    namespace PHPDaemon\Clients\Mongo;
    class Collection;
    Properties Collection Mongo Clients
    Methods Collection Mongo Clients

    Connection Mongo Clients

    namespace PHPDaemon\Clients\Mongo;
    class Connection extends \PHPDaemon\Network\ClientConnection;
    Constants Connection Mongo Clients
    Properties Connection Mongo Clients
    Methods Connection Mongo Clients

    ConnectionFinished Mongo Clients

    namespace PHPDaemon\Clients\Mongo;
    class ConnectionFinished extends \PHPDaemon\Exceptions\ConnectionFinished;

    Cursor Mongo Clients

    namespace PHPDaemon\Clients\Mongo;
    class Cursor;
    Properties Cursor Mongo Clients
    Methods Cursor Mongo Clients

    MongoId Mongo Clients

    namespace PHPDaemon\Clients\Mongo;
    class MongoId extends \MongoId;
    Methods MongoId Mongo Clients

    Pool Mongo Clients

    namespace PHPDaemon\Clients\Mongo;
    class Pool extends \PHPDaemon\Network\Client;
    Options Pool Mongo Clients
    Constants Pool Mongo Clients
    Properties Pool Mongo Clients
    Methods Pool Mongo Clients

    MySQL Clients

    namespace PHPDaemon\Clients\MySQL;

    Client for the DBMS MySQL

    Use MySQL Clients

    @TODO

    In your application, you should receive an object MySQLClient through Daemon::$appResolver->getInstanceByAppName('MySQLClient') and use as described below.

    Preparing the connection object Use MySQL Clients
    /*
      @method getConnection
      @description Establishes connection.
      @param string Optional. Address.
      @return integer Connection's ID.
    */

    You should get MySQLClientSession object by the method $MySQLClient->getConnection(), then you can put your current request / session / anything else in the current context of the connection (in the context property).

    Then use:

    $this->sql->onConnected(
        function($sql, $success) {
            if (!$success) {
                return;
            }
            // your connection-dependent code
        }
    );

    Examples MySQL Clients

    $sql->query('SHOW VARIABLES', 
       function($sql, $success) {
          $sql->context->queryResult = $sql->resultRows; // save the result
          $sql->context->wakeup(); // wake up the request immediately
       }
    );

    When the callback-function is called, $sql->context contains your subject that you put there before. $sql->resultRows stores the result in an array of associative arrays. $sql->resultFields field contains the response as an array of associative arrays.

    Connection MySQL Clients

    namespace PHPDaemon\Clients\MySQL;
    class Connection extends \PHPDaemon\Network\ClientConnection;
    Constants Connection MySQL Clients
    Properties Connection MySQL Clients
    Methods Connection MySQL Clients

    ConnectionFinished MySQL Clients

    namespace PHPDaemon\Clients\MySQL;
    class ConnectionFinished extends \PHPDaemon\Exceptions\ConnectionFinished;

    Pool MySQL Clients

    namespace PHPDaemon\Clients\MySQL;
    class Pool extends \PHPDaemon\Network\Client;
    Options Pool MySQL Clients
    Constants Pool MySQL Clients
    Methods Pool MySQL Clients

    PostgreSQL Clients

    namespace PHPDaemon\Clients\PostgreSQL;

    Connection PostgreSQL Clients

    namespace PHPDaemon\Clients\PostgreSQL;
    class Connection extends \PHPDaemon\Network\ClientConnection;
    Constants Connection PostgreSQL Clients
    Properties Connection PostgreSQL Clients
    Methods Connection PostgreSQL Clients

    ConnectionFinished PostgreSQL Clients

    namespace PHPDaemon\Clients\PostgreSQL;
    class ConnectionFinished extends \PHPDaemon\Exceptions\ConnectionFinished;

    Pool PostgreSQL Clients

    namespace PHPDaemon\Clients\PostgreSQL;
    class Pool extends \PHPDaemon\Network\Client;
    Options Pool PostgreSQL Clients

    Redis Clients

    namespace PHPDaemon\Clients\Redis;

    Connection Redis Clients

    namespace PHPDaemon\Clients\Redis;
    class Connection extends \PHPDaemon\Network\ClientConnection;
    Constants Connection Redis Clients
    Properties Connection Redis Clients
    Methods Connection Redis Clients

    Lock Redis Clients

    namespace PHPDaemon\Clients\Redis;
    class Lock;
    Methods Lock Redis Clients

    MultiEval Redis Clients

    namespace PHPDaemon\Clients\Redis;
    class MultiEval;

    Easy wrapper for queue of eval's

    Properties MultiEval Redis Clients
    Methods MultiEval Redis Clients

    Pool Redis Clients

    namespace PHPDaemon\Clients\Redis;
    class Pool extends \PHPDaemon\Network\Client;
    Options Pool Redis Clients
    Properties Pool Redis Clients
    Methods Pool Redis Clients

    Valve Clients

    namespace PHPDaemon\Clients\Valve;

    Connection Valve Clients

    namespace PHPDaemon\Clients\Valve;
    class Connection extends \PHPDaemon\Network\ClientConnection;
    Properties Connection Valve Clients
    Methods Connection Valve Clients

    Pool Valve Clients

    namespace PHPDaemon\Clients\Valve;
    class Pool extends \PHPDaemon\Network\Client;
    Options Pool Valve Clients
    Constants Pool Valve Clients
    Methods Pool Valve Clients

    WebSocket Clients

    namespace PHPDaemon\Clients\WebSocket;

    Connection WebSocket Clients

    namespace PHPDaemon\Clients\WebSocket;
    class Connection extends \PHPDaemon\Network\ClientConnection;

    Class Connection

    Constants Connection WebSocket Clients
    Properties Connection WebSocket Clients
    Methods Connection WebSocket Clients

    Pool WebSocket Clients

    namespace PHPDaemon\Clients\WebSocket;
    class Pool extends \PHPDaemon\Network\Client;
    Options Pool WebSocket Clients
    Constants Pool WebSocket Clients
    Methods Pool WebSocket Clients

    XMPP Clients

    namespace PHPDaemon\Clients\XMPP;

    Connection XMPP Clients

    namespace PHPDaemon\Clients\XMPP;
    class Connection extends \PHPDaemon\Network\ClientConnection;
    Properties Connection XMPP Clients
    Methods Connection XMPP Clients

    XMPPRoster XMPP Clients

    namespace PHPDaemon\Clients\XMPP;
    class XMPPRoster;
    Properties XMPPRoster XMPP Clients
    Methods XMPPRoster XMPP Clients

    Pool XMPP Clients

    namespace PHPDaemon\Clients\XMPP;
    class Pool extends \PHPDaemon\Network\Client;
    Options Pool XMPP Clients

    Libraries

    Cache Libraries

    namespace PHPDaemon\Cache;

    Local LRU key-value cache mechanism.

    It is used to cache shortcuts created via create_function. Also used in Clients\DNS.

    CappedStorageHits Cache Libraries

    namespace PHPDaemon\Cache;
    class CappedStorageHits extends \PHPDaemon\Cache\CappedStorage;

    CappedStorageHits

    Item Cache Libraries

    namespace PHPDaemon\Cache;
    class Item;

    Item

    Properties Item Cache Libraries
    Methods Item Cache Libraries

    CappedStorage Cache Libraries

    namespace PHPDaemon\Cache;
    class CappedStorage;

    CappedStorage

    Properties CappedStorage Cache Libraries
    Methods CappedStorage Cache Libraries

    ComplexJob Libraries

    namespace PHPDaemon\Core;
    class ComplexJob extends \ArrayAccess;

    ComplexJob class object allows you to hang up the callback function for the completion of all announced it procedures. This is useful when you need to perform a number of independent chains of action.

    Примеры ComplexJob Libraries

    $j = new ComplexJob(function($j) { // Когда всё выполнилось
       D($j['foo']); // this
       D($j['foobar']); // is
       D($j['bar']); // sparta
    });
    
    /* Add a Task */
    $j('foo', function($name, $j) { 
       $j[$name] = 'this'; // Call setResult()
    
       /* Another Problem */
       $j('foobar', function($name, $j) { 
          $j[$name] = 'is';
       });
    });
    
    /* And Another */
    $j('bar', function($name, $j) {
       $j[$name] = 'sparta';
    });
    
    $j(); // Run

    Constants ComplexJob Libraries

    Properties ComplexJob Libraries

    Methods ComplexJob Libraries

    ShellCommand Libraries

    namespace PHPDaemon\Core;
    class ShellCommand extends \PHPDaemon\Network\IOStream;

    Class is the successor IOStream, so that there are available methods such as read[ln], write[ln], and so on.

    Examples ShellCommand Libraries

    Easily perform analogue functions shell_exec ShellCommand Libraries

    ShellCommand::exec('echo "foo"', function($commandInstance, $output) {
       D($output); // foo
    });
    With additional parameters and environment variables Easily perform analogue functions shell_exec ShellCommand Libraries
    $command = 'git log';
    $cb = function($commandInstance, $output) {
         D($output); // foo
    };
    $arguments = ['-1', '--pretty' => 'oneline'];
    $env = [];
    ShellCommand::exec($command, $cb, $arguments, $env);

    Arguments will be screened using escapeshellarg

    Batch Output

    @TODO

    Properties ShellCommand Libraries

    Methods ShellCommand Libraries

    Timer Libraries

    namespace PHPDaemon\Core;
    class Timer;

    With this class can be created in the pending event (timers) time

    Examples Timer Libraries

    $i = 0;
    setTimeout(function($timer) use (&$i) {
     D("5 seconds passed!");
    
     if (++$i < 3) {
        // start the timer for another 5 seconds
        $timer->timeout();
     } else {
        D('Конец');
        $timer->free();
     }
    }, 5e6);

    Global Functions Timer Libraries

    Properties Timer Libraries

    Methods Timer Libraries

    TransportContext Libraries

    namespace PHPDaemon\Core;
    class TransportContext extends AppInstance;

    @TODO

    FS Libraries

    namespace PHPDaemon\FS;

    File FS Libraries

    namespace PHPDaemon\FS;
    class File;

    File

    Properties File FS Libraries
    Methods File FS Libraries

    FileSystem FS Libraries

    namespace PHPDaemon\FS;
    class FileSystem;

    FileSystem

    Properties FileSystem FS Libraries
    Methods FileSystem FS Libraries

    FileWatcher FS Libraries

    namespace PHPDaemon\FS;
    class FileWatcher;

    Implementation of the file watcher

    Properties FileWatcher FS Libraries
    Methods FileWatcher FS Libraries

    PubSub Libraries

    namespace PHPDaemon\PubSub;

    PubSub PubSub Libraries

    namespace PHPDaemon\PubSub;
    class PubSub;

    PubSub

    Methods PubSub PubSub Libraries

    PubSubEvent PubSub Libraries

    namespace PHPDaemon\PubSub;
    class PubSubEvent extends \SplObjectStorage;

    PubSubEvent

    Properties PubSubEvent PubSub Libraries
    Methods PubSubEvent PubSub Libraries

    SockJS Libraries

    namespace PHPDaemon\SockJS;

    Session SockJS Libraries

    namespace PHPDaemon\SockJS;
    class Session;
    Properties Session SockJS Libraries
    Methods Session SockJS Libraries

    Application SockJS Libraries

    namespace PHPDaemon\SockJS;
    class Application extends \PHPDaemon\Core\AppInstance;
    Options Application SockJS Libraries
    Properties Application SockJS Libraries
    Methods Application SockJS Libraries

    WebSocketRouteProxy SockJS Libraries

    namespace PHPDaemon\SockJS;
    class WebSocketRouteProxy;

    WebSocketConnectionProxy SockJS Libraries

    namespace PHPDaemon\SockJS;
    class WebSocketConnectionProxy;

    / TestRelay SockJS Libraries

    Application / TestRelay SockJS Libraries
    namespace PHPDaemon\SockJS\TestRelay;
    class Application extends \PHPDaemon\Core\AppInstance;
    namespace PHPDaemon\SockJS\TestRelay;
    class Close extends \PHPDaemon\WebSocket\Route;
    EchoFeed Close Application / TestRelay SockJS Libraries
    namespace PHPDaemon\SockJS\TestRelay;
    class EchoFeed extends \PHPDaemon\WebSocket\Route;
    namespace PHPDaemon\SockJS\Methods;
    class JsonpSend extends \PHPDaemon\SockJS\Methods\Generic;
    namespace PHPDaemon\SockJS\Methods;
    class Xhr extends \PHPDaemon\SockJS\Methods\Generic;
    namespace PHPDaemon\SockJS\Methods;
    class Generic extends \PHPDaemon\HTTPRequest\Generic;

    Contains some base methods

    namespace PHPDaemon\SockJS\Methods;
    class XhrSend extends \PHPDaemon\SockJS\Methods\Generic;
    namespace PHPDaemon\SockJS\Methods;
    class NotFound extends \PHPDaemon\SockJS\Methods\Generic;
    namespace PHPDaemon\SockJS\Methods;
    class Info extends \PHPDaemon\SockJS\Methods\Generic;
    namespace PHPDaemon\SockJS\Methods;
    class XhrStreaming extends \PHPDaemon\SockJS\Methods\Generic;
    namespace PHPDaemon\SockJS\Methods;
    class Eventsource extends \PHPDaemon\SockJS\Methods\Generic;
    namespace PHPDaemon\SockJS\Methods;
    class Jsonp extends \PHPDaemon\SockJS\Methods\Generic;
    namespace PHPDaemon\SockJS\Methods;
    class Welcome extends \PHPDaemon\SockJS\Methods\Generic;
    namespace PHPDaemon\SockJS\Methods;
    class Htmlfile extends \PHPDaemon\SockJS\Methods\Generic;
    namespace PHPDaemon\SockJS\Methods;
    class IFrame extends \PHPDaemon\SockJS\Methods\Generic;

    Applications

    MongoNode Applications

    namespace PHPDaemon\Examples;
    class MongoNode;

    This application provides MongoDB replication node. This makes it possible to install arbitrary hooks to add / edit / delete objects.

    Requirements MongoNode Applications

    Required module installed pecl / mongo and included phpdaemon / MongoCllient.

    MongoNode When enabled, it immediately gets the new changes in the database.

    Default:

    If the object has the property "_key" serialized its value is sent to the Memcache key under that name, which is set within the meaning of _key. When an object is deleted from the MongoDB, it is removed from Memcache.

    If the object has the property "_ev", its value is sent to the RTEP-event under the name that is specified in the value _ev.

    TelnetHoneypot Applications

    namespace PHPDaemon\Examples;
    class TelnetHoneypot;

    This application provides a simple telnet server for phpDaemon.

    [root@gf-home-server phpdaemon.wiki]# telnet 127.0.0.1 23
    Trying 127.0.0.1...
    Connected to 127.0.0.1.
    Escape character is '^]'.
    ping
    pong

    ServerStatus Applications

    namespace PHPDaemon\Applications;
    class ServerStatus;

    This application provides information about the state of phpDaemon over HTTP, similar to the console command phpd fullstatus.

    It is necessary to add conf/phpd.conf:

    ServerStatus {
        enable    1;
    }
    HTTP {
        enable 1;
        privileged;
    }

    Also conf/AppResolver.php in the method of getRequestRoute() adding a condition to start the method beginRequest() in ServerStatus application. For example, to get information about phpDaemon at http:///ServerStatus/:

    /**
     * Routes incoming request to related application. Method is for overloading.   
     * @param object Request.
     * @param object AppInstance of Upstream.
     * @return string Application's name.
     */
    public function getRequestRoute($req, $upstream) {
        if (preg_match('~^/(ServerStatus|Example)/~', $req->attrs->server['DOCUMENT_URI'], $m)) {
            return $m[1];
        }
    }

    Sample answer:

    Uptime: 1 day. 11 hour. 33 min. 51 sec.
    State of workers:
            Total: 4
            Idle: 4
            Busy: 0
            Shutdown: 20
            Pre-init: 0
            Wait-init: 0
            Init: 0

    If you are using --logworkersetstatus option, the line is:

    Utils

    Binary Utils

    namespace PHPDaemon\Utils;
    class Binary;

    This class provides a set of static methods for working with binary data.

    Methods Binary Utils

    Crypt Utils

    namespace PHPDaemon\Utils;
    class Crypt;

    This class contains methods related to cryptography.

    Methods Crypt Utils

    DateTime Utils

    namespace PHPDaemon\Utils;
    class DateTime extends \DateTime;

    Can pass a Unix timestamp to the constructor.

    Methods DateTime Utils

    Encoding Utils

    namespace PHPDaemon\Utils;
    class Encoding;

    Third-party libraries — forceutf8

    Methods Encoding Utils

    IRC Utils

    namespace PHPDaemon\Utils;
    class IRC;

    Class used in the IRC-client and IRC-bouncer

    Properties IRC Utils

    Methods IRC Utils

    MIME Utils

    namespace PHPDaemon\Utils;
    class MIME;

    Methods MIME Utils

    ShmEntity Utils

    namespace PHPDaemon\Utils;
    class ShmEntity;

    Elastic heap storage in the shared memory

    It used to store an array of workflow status.

    Methods ShmEntity Utils

    Terminal Utils

    namespace PHPDaemon\Utils;
    class Terminal;


    This class needs work: lacks full ncurses support. If you would like to help, click on the cat!

    Methods Terminal Utils

    Structures

    ObjectStorage Structures

    namespace PHPDaemon\Structures;
    class ObjectStorage extends \SplObjectStorage;

    This class provides an object store with a few additional methods

    You can subclass one

    Methods ObjectStorage Structures

    PriorityQueueCallbacks Structures

    namespace PHPDaemon\Structures;
    class PriorityQueueCallbacks extends \SplPriorityQueue;

    Used in Network/Client to store calls, until all available connections are busy

    StackCallbacks Structures

    namespace PHPDaemon\Structures;
    class StackCallbacks extends \SplStack;

    This class provides a stack of callback functions with several additional methods

    Used in Network/Client to store the callback stack

    Methods StackCallbacks Structures

    Traits

    Traits

    This section describes the included traits available to developers.

    ClassWatchdog Traits

    namespace PHPDaemon\Traits;
    trait ClassWatchdog;

    This trait is already used in all base classes and there is no need to reuse it when inheriting from them.

    This trait is needed to prevent an E_ERROR (Fatal error) level error from occurring when calling a non-existent method. E_ERROR, however, interrupts the entire workflow, which is unacceptable in the phpDaemon reality. It is strongly recommended for all classes to use.

    This trait defines the following magic methods:

    StaticObjectWatchdog Traits

    namespace PHPDaemon\Traits;
    trait StaticObjectWatchdog;

    This trait is already used in all base classes and there is no need to reuse it when inheriting from them.

    A PHP machine can store a set of object properties in two ways: as a fixed array and as an associative hash table using the [B-tree] (http://ru.wikipedia.org/wiki/B-дерево). Initially, when creating any object, properties are stored in the form of an array with quick access. At the first attempt to set the value of a property not declared by the directive visibility $name, the set of properties is converted to an associative table. The same happens when you delete (unset) any property). This operation in itself is not the fastest, especially with a large number of properties), but access to properties after it slows down. Of course, there are objects with intentionally dynamic set of properties, which are akin to associative arrays and they are all right. But it often happens that the programmer forgets to add a property declaration or even misprints its name. Sometimes it leads to severe performance degradation which is difficult to investigate.

    Before saying that PHP is slow, it's a good idea to learn how to cook it.

    This trait defines the following magic methods:

    StrictStaticObjectWatchdog Traits

    namespace PHPDaemon\Traits;
    trait StrictStaticObjectWatchdog;

    The behavior is similar to StaticObjectWatchdog, but this trait throws an exception instead of logging.

    Defines the following magic methods:

    DeferredEventHandlers Traits

    namespace PHPDaemon\Traits;
    trait DeferredEventHandlers;

    This trait implements a deferred events mechanism for an object.

    class MyClass {
        use \PHPDaemon\Traits\DeferredEventHandlers;
        protected function onSomethingEvent($foo, $bar) {
            return function($ev) {
                list ($foo, $bar = $ev->args;
                $ev->setResult("Foo is $foo, bar is $bar");
            };
        }
    }
    $o = new MyClass;
    $o->onSomething(function($ev) {
        D($ev->result);
        // Foo is fooo, bar is barr
    }, 'foo', 'barr');
    
    $o->onSomething(function($ev) {
        D($ev->result);
        // Foo is fooo, bar is barr
    });

    При этом когда результат уже установлен, производящее его замыкание не будет вызвано повторно. Не нужно беспокоиться о повторном вызове еще до того как результат установлен, ожидающие замыкания будут вызваны правильно.

    EventHandlers Traits

    namespace PHPDaemon\Traits;
    trait EventHandlers;

    This trait implements a simple PUB/SUB mechanism for an object.

    class MyClass {
        use \PHPDaemon\Traits\EventHandlers;
    }
    $o = new MyClass;
    
    $o->on('smth', function($o, $foo, $bar) {
        D("Foo is $foo, bar is $bar");
    });
    
    $o->trigger('smth', 'foo', 'barr');
    

    Do not forget that when deleting such an object, you should call the cleanupEventHandlers(), to avoid memory leaks.

    Sessions Traits

    namespace PHPDaemon\Traits;
    trait Sessions;

    This trait implements a session mechanism. The mechanism is implemented completely on its own and not as a mere wrapper around session_* functions.

    Why can't we just use the native PHP session mechanism?

    As with the native implementation, the behaviour of sessions is based on php.ini.

    The current implementation supports storing sessions in files, session.serialize_handler = php|php_binary, lock r+! files - milar to the native one - to prevent race condition.

    You can safely use PhpDaemon with existing sessions, the serialization is compatible with native (session_encode, session_decode).

    Usage examples:

    $this->onSessionStart(function ($event) {
        if (!$event->getResult()) {
            //Session open failed
        }
        //Session open succeed
    });

    This trait is used in HTTPRequest и Servers\WebSocket\Route

    DNode Traits

    trait \PHPDaemon\WebSocket\Traits\DNode

    This trait is applicable in classes inherited from Servers\WebSocket\Route

    The trait implements the server portion of the protocol DNode, which is used for Remote procedure call (RPC).

    Для подключение примеси нужно внести use \PHPDaemon\WebSocket\Traits\DNode в определение своего класса-наследника Servers\WebSocket\Route.

    Затем необходимо определить методы, доступные клиенту. Фактически это делает метод defineLocalMethods, который должен вызываться в onHandshake.

    Давайте, для примера, создадим метод dummy с аргументами $foo, $bar и $callback:

    protected function dummyMethod($foo, $bar, $callback) {
        if (!static::ensureCallback($callback)) {
            /* $callback не содержит функцию обратного вызова */
            return;
        }
        $callback(md5($foo ^ $bar));
    }

    При обращении dummy('Hello', 'World', function(result) {...}) ответом будет вызов этой функции с аргументом bd7815679056a50c3f545b159ce5e385 — результатом выполнения md5('Hello' ^ 'World')

    В качестве аргументов можно передавать передавать собственные функции обратного вызова, но учтите, что они удаляются из памяти после вызова, если возвратное значение не является true. Таким образом, следует понимать ожидается ли повторный вызов, и в этом случае возвращать true. Это делается во избежание утечек памяти.

    Для вызова удаленного метода по имени, используйте callRemote.

    Как вы могли заметить, пример dummyMethod использует вызов static::ensureCallback($callback). Всегда нужно проверять переданный аргумент с помощью ensureCallback перед его исполнением. В противном случае, это обернётся серьёзной брешью безопасности.

    Methods DNode Traits

    Network

    Pool Network

    namespace PHPDaemon\Network;
    abstract class Pool extends ObjectStorage;

    Keeps objects in the currently active compound and OtkrytyySoket.

    Poole (client or server) can be instantiated from a user application, such as:

    $this->httpclient = \PHPDaemon\Clients\HTTP\Pool::getInstance();

    or

    /* ... */
    $this->pool = \PHPDaemon\Servers\FlashPolicy\Pool::getInstance([
        'listen' => 'tcp://0.0.0.0:843'
    ]);
    $this->pool->onReady();
    /* ... */

    But don't forget to send onReady(), onShutdown() and onConfigUpdated() events.

    In most cases, the server is run by the Pool application of the same name.

    # context for ssl connection (optional)
    TransportContext:myContext {
        tls;
        certFile "/path/to/cert.pem";
        pkFile "/path/to/privkey.pem";
        passphrase "";
        verifyPeer true;
        allowSelfSigned true;
    }
    
    # listening to port 80 and 443
    Pool:HTTPServer {
        listen "tcp://0.0.0.0:80", "tcp://0.0.0.0:443##myContext";
        port 80;
        privileged;
        maxconcurrency 1;
    }

    Properties Pool Network

    Methods Pool Network

    Client Network

    namespace PHPDaemon\Network;
    abstract class Client extends Pool;

    @TODO

    Options Client Network

    Methods Client Network

    ClientConnection Network

    namespace PHPDaemon\Network;
    class ClientConnection extends Connection;

    @TODO

    Methods ClientConnection Network

    Connection Network

    namespace PHPDaemon\Network;
    abstract class Connection extends IOStream;

    @TODO

    Methods Connection Network

    IOStream Network

    namespace PHPDaemon\Network;
    abstract class IOStream;

    @TODO

    Constants IOStream Network

    Properties IOStream Network

    Methods IOStream Network

    Server Network

    namespace PHPDaemon\Network;
    abstract class Server extends Pool;

    @TODO

    Properties Server Network

    Methods Server Network

    HTTPRequest

    Generic HTTPRequest

    namespace PHPDaemon\HTTPRequest;
    abstract class Generic extends \PHPDaemon\Request\Generic;

    @TODO

    Properties Generic HTTPRequest

    Methods Generic HTTPRequest

    Input HTTPRequest

    namespace PHPDaemon\HTTPRequest;
    class Input extends \EventBuffer;

    @TODO

    FAQ

    How to make the event, which is called after a specified time interval?

    See. Library/Timer

    Publications

    ...

    Contribute

    If you want to help the project, then do not hesitate to start even if you have only a bit of time for it. Any help is appreciated.

    This documentation Contribute

    We are struggling to minimize amount of undocumented parts, but we are running out of hands. Even a paragraph written in 10 minutes is a big deal.

    Making changes This documentation Contribute

    Consider writing in the language you know best among all others. If you are bold enough to add new language, base it upon the most similar one of existing languages.

    1. Fork a repository kakserpom/daemon.io
    2. Change Markdown (.md) files in folder ./docs/<language>/
    3. Compile index.html by executing ./docs/build
    4. Look how it looks in browser
    5. Send Pull Request

    Want to see changes in browser without running the command? Run watch -n1 ./docs/build — it shall be rebuilt every second

    Format of documentation This documentation Contribute

    We use the Markdown with some extensions.

    For your convenience, documentation is split between many small files. Including a file: <!-- import filepath.md -->. Path is relative.

    Constants are used for i18n and shortcuts for frequently used templates. They may be defined as simple as that: <!-- pvar Name Value -->

    Mandatory i18n contants lang, title and menu-* must be present in each translation of this documentation.

    Constants may be used as templates. Calling a template: {Name Value1 Value1...}. Values will be places in result instead of %s.

    Example of a template: <!-- pvar tpl-outlink <a target="_blank" href="%s">%s<i class="fa fa-external-link"></i></a> -->

    Example of its usage: {tpl-outlink http://en.wikipedia.org/wiki/Markdown Markdown}

    Headings may be defined like that:

    anchor - an identifier for navigation which takes place in URL. Allowed symbols are [a-zA-Z0-9_-]. Must be unique among anchors of its level to avoid URL collisions.

    Formatted heading is used in case if heading in the page body should differ from heading in the navigation bar.

    Examples:

    If you are adding new heading, make sure that anchor is written in English (strictly) and is simple and informative. Anchors are not supposed to be translated

    You can set CSS class of list element.

     -.n Element without list mark
     -.n.ti Element without list mark with indentation from the previous one

    The following classes are currently in use:

    Italic and bold works with *, _ is not available due to the compatibility reasons.

    The code is wrapped into apostrophes `...` with the additional possibility to use modifiers and CSS classes. Modifiers are options that enable additional text processing. Modifiers and classes are written after the opening apostrophe and must be closed with an additional one before the text starts. Modifiers are specified by a preceding : (colon). Each modifier is indicated by one single letter. Classes are specified with a leading period.

    When specifying both modifiers and classes at the same time, the modifiers must be written first.

    List of modifiers:

    Only the class can be used at the moment, but it is better to specify the modifier :c`.

    Usage examples:

    Multi-line code with additional syntax highlighting and CSS classes. The code containing the configuration is indicated by the ruby syntax.

    The only available class at the moment is `.inline' for method definitions.

    Examples:

    ```php.inline void public post ( url $url, array $data, array $params ) void public post ( url $url, array $data, callable $resultcb ) ```

    ```ruby Pool:HTTPServer {     listen "tcp://0.0.0.0:80", "tcp://0.0.0.0:443##myContext";     port 80;     privileged;     maxconcurrency 1; } ```

    PHPDoc Contribute

    Similarly, to fill in any gaps in the PHPDoc comments of the code, fork main respository, make changes and send a Pull Request.

    Please note that all PHPDoc comments are written strictly in English.

    Software code Contribute

    Improvements to the program code are always welcome. If you have a module to publish and you think it deserves to be included in the main repository, send a Pull Request. Do the same with existing code improvements.

    Authors of documentation

    English proofreading Authors of documentation

    ...

    Old contributors

    Fork me on GitHub