Php/docs/event.examples

来自菜鸟教程
跳转至:导航、​搜索

范例

Example #1 Simple HTTP client

<?php// Read callbackfunction readcb($bev, $base) {    //$input = $bev->input; //$bev->getInput();    //$pos = $input->search("TTP");    $pos = $bev->input->search("TTP");    while (($n = $bev->input->remove($buf, 1024)) > 0) {        echo $buf;    }}// Event callbackfunction eventcb($bev, $events, $base) {    if ($events & EventBufferEvent::CONNECTED) {        echo "Connected.\n";    } elseif ($events & (EventBufferEvent::ERROR | EventBufferEvent::EOF)) {        if ($events & EventBufferEvent::ERROR) {            echo "DNS error: ", $bev->getDnsErrorString(), PHP_EOL;        }        echo "Closing\n";        $base->exit();        exit("Done\n");    }}if ($argc != 3) {    echo <<<EOSTrivial HTTP 0.x clientSyntax: php {$argv[0]} [hostname] [resource]Example: php {$argv[0]} www.google.com /EOS;    exit();}$base = new EventBase();$dns_base = new EventDnsBase($base, TRUE); // We'll use async DNS resolvingif (!$dns_base) {    exit("Failed to init DNS Base\n");}$bev = new EventBufferEvent($base, /* use internal socket */ NULL,    EventBufferEvent::OPT_CLOSE_ON_FREE | EventBufferEvent::OPT_DEFER_CALLBACKS,    "readcb", /* writecb */ NULL, "eventcb");if (!$bev) {    exit("Failed creating bufferevent socket\n");}//$bev->setCallbacks("readcb", /* writecb */ NULL, "eventcb", $base);$bev->enable(Event::READ | Event::WRITE);$output = $bev->output; //$bev->getOutput();if (!$output->add(    "GET {$argv[2]} HTTP/1.0\r\n".    "Host: {$argv[1]}\r\n".    "Connection: Close\r\n\r\n")) {    exit("Failed adding request to output buffer\n");}if (!$bev->connectHost($dns_base, $argv[1], 80, EventUtil::AF_UNSPEC)) {    exit("Can't connect to host {$argv[1]}\n");}$base->dispatch();?>

以上例程的输出类似于:


Connected.
HTTP/1.1 301 Moved Permanently
Date: Fri, 01 Mar 2013 18:47:48 GMT
Location: http://www.google.co.uk/
Content-Type: text/html; charset=UTF-8
Cache-Control: public, max-age=2592000
Server: gws
Content-Length: 221
X-XSS-Protection: 1; mode=block
X-Frame-Options: SAMEORIGIN
Age: 133438
Expires: Sat, 30 Mar 2013 05:39:28 GMT
Connection: close

<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>301 Moved</TITLE></HEAD><BODY>
<H1>301 Moved</H1>
The document has moved
<A HREF="http://www.google.co.uk/">here</A>.
</BODY></HTML>
Closing
Done

Example #2 HTTP client using asynchronous DNS resolver

<?php/* * 1. Connect to 127.0.0.1 at port 80 * by means of EventBufferEvent::connect(). * * 2. Request /index.cphp via HTTP/1.0 * using the output buffer. * * 3. Asyncronously read the response and print it to stdout. */// Read callbackfunction readcb($bev, $base) {    $input = $bev->getInput();    while (($n = $input->remove($buf, 1024)) > 0) {        echo $buf;    }}// Event callbackfunction eventcb($bev, $events, $base) {    if ($events & EventBufferEvent::CONNECTED) {        echo "Connected.\n";    } elseif ($events & (EventBufferEvent::ERROR | EventBufferEvent::EOF)) {        if ($events & EventBufferEvent::ERROR) {            echo "DNS error: ", $bev->getDnsErrorString(), PHP_EOL;        }        echo "Closing\n";        $base->exit();        exit("Done\n");    }}$base = new EventBase();echo "step 1\n";$bev = new EventBufferEvent($base, /* use internal socket */ NULL,    EventBufferEvent::OPT_CLOSE_ON_FREE | EventBufferEvent::OPT_DEFER_CALLBACKS);if (!$bev) {    exit("Failed creating bufferevent socket\n");}echo "step 2\n";$bev->setCallbacks("readcb", /* writecb */ NULL, "eventcb", $base);$bev->enable(Event::READ | Event::WRITE);echo "step 3\n";// Send request$output = $bev->getOutput();if (!$output->add(    "GET /index.cphp HTTP/1.0\r\n".    "Connection: Close\r\n\r\n")) {    exit("Failed adding request to output buffer\n");}/* Connect to the host syncronously.We know the IP, and don't need to resolve DNS. */if (!$bev->connect("127.0.0.1:80")) {    exit("Can't connect to host\n");}// Dispatch pending events$base->dispatch();?>

Example #3 Echo server

<?php/* * Simple echo server based on libevent's connection listener. * * Usage: * 1) In one terminal window run: * * $ php listener.php 9881 * * 2) In another terminal window open up connection, e.g.: * * $ nc 127.0.0.1 9881 * * 3) start typing. The server should repeat the input. */class MyListenerConnection {    private $bev, $base;    public function __destruct() {        $this->bev->free();    }    public function __construct($base, $fd) {        $this->base = $base;        $this->bev = new EventBufferEvent($base, $fd, EventBufferEvent::OPT_CLOSE_ON_FREE);        $this->bev->setCallbacks(array($this, "echoReadCallback"), NULL,            array($this, "echoEventCallback"), NULL);        if (!$this->bev->enable(Event::READ)) {            echo "Failed to enable READ\n";            return;        }    }    public function echoReadCallback($bev, $ctx) {        // Copy all the data from the input buffer to the output buffer        // Variant #1        $bev->output->addBuffer($bev->input);        /* Variant #2 */        /*        $input    = $bev->getInput();        $output = $bev->getOutput();        $output->addBuffer($input);        */    }    public function echoEventCallback($bev, $events, $ctx) {        if ($events & EventBufferEvent::ERROR) {            echo "Error from bufferevent\n";        }        if ($events & (EventBufferEvent::EOF | EventBufferEvent::ERROR)) {            //$bev->free();            $this->__destruct();        }    }}class MyListener {    public $base,        $listener,        $socket;    private $conn = array();    public function __destruct() {        foreach ($this->conn as &$c) $c = NULL;    }    public function __construct($port) {        $this->base = new EventBase();        if (!$this->base) {            echo "Couldn't open event base";            exit(1);        }        // Variant #1        /*        $this->socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);        if (!socket_bind($this->socket, '0.0.0.0', $port)) {            echo "Unable to bind socket\n";            exit(1);        }        $this->listener = new EventListener($this->base,            array($this, "acceptConnCallback"), $this->base,            EventListener::OPT_CLOSE_ON_FREE | EventListener::OPT_REUSEABLE,            -1, $this->socket);         */        // Variant #2         $this->listener = new EventListener($this->base,             array($this, "acceptConnCallback"), $this->base,             EventListener::OPT_CLOSE_ON_FREE | EventListener::OPT_REUSEABLE, -1,             "0.0.0.0:$port");        if (!$this->listener) {            echo "Couldn't create listener";            exit(1);        }        $this->listener->setErrorCallback(array($this, "accept_error_cb"));    }    public function dispatch() {        $this->base->dispatch();    }    // This callback is invoked when there is data to read on $bev    public function acceptConnCallback($listener, $fd, $address, $ctx) {        // We got a new connection! Set up a bufferevent for it. */        $base = $this->base;        $this->conn[] = new MyListenerConnection($base, $fd);    }    public function accept_error_cb($listener, $ctx) {        $base = $this->base;        fprintf(STDERR, "Got an error %d (%s) on the listener. "            ."Shutting down.\n",            EventUtil::getLastSocketErrno(),            EventUtil::getLastSocketError());        $base->exit(NULL);    }}$port = 9808;if ($argc > 1) {    $port = (int) $argv[1];}if ($port <= 0 || $port > 65535) {    exit("Invalid port");}$l = new MyListener($port);$l->dispatch();?>

Example #4 SSL echo server

<?php/* * SSL echo server * * To test: * 1) Run: * $ php examples/ssl-echo-server/server.php 9998 * * 2) in another terminal window run: * $ socat - SSL:127.0.0.1:9998,verify=1,cafile=examples/ssl-echo-server/cert.pem */class MySslEchoServer {    public $port,        $base,        $bev,        $listener,        $ctx;    function __construct ($port, $host = "127.0.0.1") {        $this->port = $port;        $this->ctx = $this->init_ssl();        if (!$this->ctx) {            exit("Failed creating SSL context\n");        }        $this->base = new EventBase();        if (!$this->base) {            exit("Couldn't open event base\n");        }        $this->listener = new EventListener($this->base,            array($this, "ssl_accept_cb"), $this->ctx,            EventListener::OPT_CLOSE_ON_FREE | EventListener::OPT_REUSEABLE,            -1, "$host:$port");        if (!$this->listener) {            exit("Couldn't create listener\n");        }        $this->listener->setErrorCallback(array($this, "accept_error_cb"));    }    function dispatch() {        $this->base->dispatch();    }    // This callback is invoked when there is data to read on $bev.    function ssl_read_cb($bev, $ctx) {        $in = $bev->input; //$bev->getInput();        printf("Received %zu bytes\n", $in->length);        printf("----- data ----\n");        printf("%ld:\t%s\n", (int) $in->length, $in->pullup(-1));        $bev->writeBuffer($in);    }    // This callback is invoked when some even occurs on the event listener,    // e.g. connection closed, or an error occurred    function ssl_event_cb($bev, $events, $ctx) {        if ($events & EventBufferEvent::ERROR) {            // Fetch errors from the SSL error stack            while ($err = $bev->sslError()) {                fprintf(STDERR, "Bufferevent error %s.\n", $err);            }        }        if ($events & (EventBufferEvent::EOF | EventBufferEvent::ERROR)) {            $bev->free();        }    }    // This callback is invoked when a client accepts new connection    function ssl_accept_cb($listener, $fd, $address, $ctx) {        // We got a new connection! Set up a bufferevent for it.        $this->bev = EventBufferEvent::sslSocket($this->base, $fd, $this->ctx,            EventBufferEvent::SSL_ACCEPTING, EventBufferEvent::OPT_CLOSE_ON_FREE);        if (!$this->bev) {            echo "Failed creating ssl buffer\n";            $this->base->exit(NULL);            exit(1);        }        $this->bev->enable(Event::READ);        $this->bev->setCallbacks(array($this, "ssl_read_cb"), NULL,            array($this, "ssl_event_cb"), NULL);    }    // This callback is invoked when we failed to setup new connection for a client    function accept_error_cb($listener, $ctx) {        fprintf(STDERR, "Got an error %d (%s) on the listener. "            ."Shutting down.\n",            EventUtil::getLastSocketErrno(),            EventUtil::getLastSocketError());        $this->base->exit(NULL);    }    // Initialize SSL structures, create an EventSslContext    // Optionally create self-signed certificates    function init_ssl() {        // We *must* have entropy. Otherwise there's no point to crypto.        if (!EventUtil::sslRandPoll()) {            exit("EventUtil::sslRandPoll failed\n");        }        $local_cert = __DIR__."/cert.pem";        $local_pk   = __DIR__."/privkey.pem";        if (!file_exists($local_cert) || !file_exists($local_pk)) {            echo "Couldn't read $local_cert or $local_pk file.  To generate a key\n",                "and self-signed certificate, run:\n",                "  openssl genrsa -out $local_pk 2048\n",                "  openssl req -new -key $local_pk -out cert.req\n",                "  openssl x509 -req -days 365 -in cert.req -signkey $local_pk -out $local_cert\n";            return FALSE;        }        $ctx = new EventSslContext(EventSslContext::SSLv3_SERVER_METHOD, array (             EventSslContext::OPT_LOCAL_CERT  => $local_cert,             EventSslContext::OPT_LOCAL_PK    => $local_pk,             //EventSslContext::OPT_PASSPHRASE  => "echo server",             EventSslContext::OPT_VERIFY_PEER => true,             EventSslContext::OPT_ALLOW_SELF_SIGNED => false,        ));        return $ctx;    }}// Allow to override the port$port = 9999;if ($argc > 1) {    $port = (int) $argv[1];}if ($port <= 0 || $port > 65535) {    exit("Invalid port\n");}$l = new MySslEchoServer($port);$l->dispatch();?>

Example #5 Signal handler

<?php/*Launch it in a terminal window:$ php examples/signal.phpIn another terminal window find out the pid and send SIGTERM, e.g.:$ ps aux | grep exampruslan    3976  0.2  0.0 139896 11256 pts/1    S+   10:25   0:00 php examples/signal.phpruslan    3978  0.0  0.0   9572   864 pts/2    S+   10:26   0:00 grep --color=auto examp$ kill -TERM 3976At the first terminal window you should catch the following:Caught signal 15*/class MyEventSignal {    private $base;    function __construct($base) {        $this->base = $base;    }    function eventSighandler($no, $c) {        echo "Caught signal $no\n";        event_base_loopexit($c->base);    }}$base = event_base_new();$c    = new MyEventSignal($base);$no   = SIGTERM;$ev   = evsignal_new($base, $no, array($c,'eventSighandler'), $c);evsignal_add($ev);event_base_loop($base);?>

Example #6 Use libevent's loop to process requests of `eio' extension

<?php// Callback for eio_nop()function my_nop_cb($d, $r) {    echo "step 6\n";}$dir = "/tmp/abc-eio-temp";if (file_exists($dir)) {    rmdir($dir);}echo "step 1\n";$base = new EventBase();echo "step 2\n";eio_init();eio_mkdir($dir, 0750, EIO_PRI_DEFAULT, "my_nop_cb");$event = new Event($base, eio_get_event_stream(),    Event::READ | Event::PERSIST, function ($fd, $events, $base) {    echo "step 5\n";    while (eio_nreqs()) {        eio_poll();    }    $base->stop();}, $base);echo "step 3\n";$event->add();echo "step 4\n";$base->dispatch();echo "Done\n";?>

Example #7 Miscellaneous

<?php/* {{{ Config & supported stuff */echo "Supported methods:\n";foreach (Event::getSupportedMethods() as $m) {    echo $m, PHP_EOL;}// Avoiding "select" method$cfg = new EventConfig();if ($cfg->avoidMethod("select")) {    echo "`select' method avoided\n";}// Create event_base associated with the config$base = new EventBase($cfg);echo "Event method used: ", $base->getMethod(), PHP_EOL;echo "Features:\n";$features = $base->getFeatures();($features & EventConfig::FEATURE_ET) and print("ET - edge-triggered IO\n");($features & EventConfig::FEATURE_O1) and print("O1 - O(1) operation for adding/deletting events\n");($features & EventConfig::FEATURE_FDS) and print("FDS - arbitrary file descriptor types, and not just sockets\n");// Require FDS featureif ($cfg->requireFeatures(EventConfig::FEATURE_FDS)) {    echo "FDS feature is now requried\n";    $base = new EventBase($cfg);    ($base->getFeatures() & EventConfig::FEATURE_FDS)        and print("FDS - arbitrary file descriptor types, and not just sockets\n");}/* }}} *//*  Event::PERSIST, function ($fd, $events, $arg) {    static $max_iterations = 0;    if (++$max_iterations >= 5) {        /* exit after 5 iterations with timeout of 2.33 seconds */        echo "Stopping...\n";        $arg[0]->exit(2.33);    }    echo fgets($fd);}, array (&$base));$event->add();$base->loop();/* Base  */?>

Example #8 Simple HTTP server

<?php/* * Simple HTTP server. * * To test it: * 1) Run it on a port of your choice, e.g.: * $ php examples/http.php 8010 * 2) In another terminal connect to some address on this port * and make GET or POST request(others are turned off here), e.g.: * $ nc -t 127.0.0.1 8010 * POST /about HTTP/1.0 * Content-Type: text/plain * Content-Length: 4 * Connection: close * (press Enter) * * It will output * a=12 * HTTP/1.0 200 OK * Content-Type: text/html; charset=ISO-8859-1 * Connection: close * * $ nc -t 127.0.0.1 8010 * GET /dump HTTP/1.0 * Content-Type: text/plain * Content-Encoding: UTF-8 * Connection: close * (press Enter) * * It will output: * HTTP/1.0 200 OK * Content-Type: text/html; charset=ISO-8859-1 * Connection: close * (press Enter) * * $ nc -t 127.0.0.1 8010 * GET /unknown HTTP/1.0 * Connection: close * * It will output: * HTTP/1.0 200 OK * Content-Type: text/html; charset=ISO-8859-1 * Connection: close * * 3) See what the server outputs on the previous terminal window. */function _http_dump($req, $data) {    static $counter      = 0;    static $max_requests = 2;    if (++$counter >= $max_requests)  {        echo "Counter reached max requests $max_requests. Exiting\n";        exit();    }    echo __METHOD__, " called\n";    echo "request:"; var_dump($req);    echo "data:"; var_dump($data);    echo "\n===== DUMP =====\n";    echo "Command:", $req->getCommand(), PHP_EOL;    echo "URI:", $req->getUri(), PHP_EOL;    echo "Input headers:"; var_dump($req->getInputHeaders());    echo "Output headers:"; var_dump($req->getOutputHeaders());    echo "\n >> Sending reply ...";    $req->sendReply(200, "OK");    echo "OK\n";    echo "\n >> Reading input buffer ...\n";    $buf = $req->getInputBuffer();    while ($s = $buf->readLine(EventBuffer::EOL_ANY)) {        echo $s, PHP_EOL;    }    echo "No more data in the buffer\n";}function _http_about($req) {    echo __METHOD__, PHP_EOL;    echo "URI: ", $req->getUri(), PHP_EOL;    echo "\n >> Sending reply ...";    $req->sendReply(200, "OK");    echo "OK\n";}function _http_default($req, $data) {    echo __METHOD__, PHP_EOL;    echo "URI: ", $req->getUri(), PHP_EOL;    echo "\n >> Sending reply ...";    $req->sendReply(200, "OK");    echo "OK\n";}$port = 8010;if ($argc > 1) {    $port = (int) $argv[1];}if ($port <= 0 || $port > 65535) {    exit("Invalid port");}$base = new EventBase();$http = new EventHttp($base);$http->setAllowedMethods(EventHttpRequest::CMD_GET | EventHttpRequest::CMD_POST);$http->setCallback("/dump", "_http_dump", array(4, 8));$http->setCallback("/about", "_http_about");$http->setDefaultCallback("_http_default", "custom data value");$http->bind("0.0.0.0", 8010);$base->loop();?>

以上例程的输出类似于:


a=12
HTTP/1.0 200 OK
Content-Type: text/html; charset=ISO-8859-1
Connection: close

HTTP/1.0 200 OK
Content-Type: text/html; charset=ISO-8859-1
Connection: close
(press Enter)

HTTP/1.0 200 OK
Content-Type: text/html; charset=ISO-8859-1
Connection: close

Example #9 Simple HTTPS server

<?php/* * Simple HTTPS server. * * 1) Run the server: `php examples/https.php 9999` * 2) Test it: `php examples/ssl-connection.php 9999` */function _http_dump($req, $data) {    static $counter      = 0;    static $max_requests = 200;    if (++$counter >= $max_requests)  {        echo "Counter reached max requests $max_requests. Exiting\n";        exit();    }    echo __METHOD__, " called\n";    echo "request:"; var_dump($req);    echo "data:"; var_dump($data);    echo "\n===== DUMP =====\n";    echo "Command:", $req->getCommand(), PHP_EOL;    echo "URI:", $req->getUri(), PHP_EOL;    echo "Input headers:"; var_dump($req->getInputHeaders());    echo "Output headers:"; var_dump($req->getOutputHeaders());    echo "\n >> Sending reply ...";    $req->sendReply(200, "OK");    echo "OK\n";    $buf = $req->getInputBuffer();    echo "\n >> Reading input buffer (", $buf->length, ") ...\n";    while ($s = $buf->read(1024)) {        echo $s;    }    echo "\nNo more data in the buffer\n";}function _http_about($req) {    echo __METHOD__, PHP_EOL;    echo "URI: ", $req->getUri(), PHP_EOL;    echo "\n >> Sending reply ...";    $req->sendReply(200, "OK");    echo "OK\n";}function _http_default($req, $data) {    echo __METHOD__, PHP_EOL;    echo "URI: ", $req->getUri(), PHP_EOL;    echo "\n >> Sending reply ...";    $req->sendReply(200, "OK");    echo "OK\n";}function _http_400($req) {    $req->sendError(400);}function _init_ssl() {    $local_cert = __DIR__."/ssl-echo-server/cert.pem";    $local_pk   = __DIR__."/ssl-echo-server/privkey.pem";    $ctx = new EventSslContext(EventSslContext::SSLv3_SERVER_METHOD, array (        EventSslContext::OPT_LOCAL_CERT  => $local_cert,        EventSslContext::OPT_LOCAL_PK    => $local_pk,        //EventSslContext::OPT_PASSPHRASE  => "test",        EventSslContext::OPT_ALLOW_SELF_SIGNED => true,    ));    return $ctx;}$port = 9999;if ($argc > 1) {    $port = (int) $argv[1];}if ($port <= 0 || $port > 65535) {    exit("Invalid port");}$ip = '0.0.0.0';$base = new EventBase();$ctx  = _init_ssl();$http = new EventHttp($base, $ctx);$http->setAllowedMethods(EventHttpRequest::CMD_GET | EventHttpRequest::CMD_POST);$http->setCallback("/dump", "_http_dump", array(4, 8));$http->setCallback("/about", "_http_about");$http->setCallback("/err400", "_http_400");$http->setDefaultCallback("_http_default", "custom data value");$http->bind($ip, $port);$base->dispatch();

Example #10 OpenSSL connection

<?php/* * Sample OpenSSL client. * * Usage: * 1) Launch a server, e.g.: * $ php examples/https.php 9999 * * 2) Launch the client in another terminal: * $ php examples/ssl-connection.php 9999 */function _request_handler($req, $base) {    echo __FUNCTION__, PHP_EOL;    if (is_null($req)) {        echo "Timed out\n";    } else {        $response_code = $req->getResponseCode();        if ($response_code == 0) {            echo "Connection refused\n";        } elseif ($response_code != 200) {            echo "Unexpected response: $response_code\n";        } else {            echo "Success: $response_code\n";            $buf = $req->getInputBuffer();            echo "Body:\n";            while ($s = $buf->readLine(EventBuffer::EOL_ANY)) {                echo $s, PHP_EOL;            }        }    }    $base->exit(NULL);}function _init_ssl() {    $ctx = new EventSslContext(EventSslContext::SSLv3_CLIENT_METHOD, array ());    return $ctx;}// Allow to override the port$port = 9999;if ($argc > 1) {    $port = (int) $argv[1];}if ($port <= 0 || $port > 65535) {    exit("Invalid port\n");}$host = '127.0.0.1';$ctx = _init_ssl();if (!$ctx) {    trigger_error("Failed creating SSL context", E_USER_ERROR);}$base = new EventBase();if (!$base) {    trigger_error("Failed to initialize event base", E_USER_ERROR);}$conn = new EventHttpConnection($base, NULL, $host, $port, $ctx);$conn->setTimeout(50);$req = new EventHttpRequest("_request_handler", $base);$req->addHeader("Host", $host, EventHttpRequest::OUTPUT_HEADER);$buf = $req->getOutputBuffer();$buf->add("<html>HTML TEST</html>");//$req->addHeader("Content-Length", $buf->length, EventHttpRequest::OUTPUT_HEADER);//$req->addHeader("Connection", "close", EventHttpRequest::OUTPUT_HEADER);$conn->makeRequest($req, EventHttpRequest::CMD_POST, "/dump");$base->dispatch();echo "END\n";?>

Example #11 EventHttpConnection::makeRequest() example

<?phpfunction _request_handler($req, $base) {    echo __FUNCTION__, PHP_EOL;    if (is_null($req)) {        echo "Timed out\n";    } else {        $response_code = $req->getResponseCode();        if ($response_code == 0) {            echo "Connection refused\n";        } elseif ($response_code != 200) {            echo "Unexpected response: $response_code\n";        } else {            echo "Success: $response_code\n";            $buf = $req->getInputBuffer();            echo "Body:\n";            while ($s = $buf->readLine(EventBuffer::EOL_ANY)) {                echo $s, PHP_EOL;            }        }    }    $base->exit(NULL);}$address = "127.0.0.1";$port = 80;$base = new EventBase();$conn = new EventHttpConnection($base, NULL, $address, $port);$conn->setTimeout(5);$req = new EventHttpRequest("_request_handler", $base);$req->addHeader("Host", $address, EventHttpRequest::OUTPUT_HEADER);$req->addHeader("Content-Length", "0", EventHttpRequest::OUTPUT_HEADER);$conn->makeRequest($req, EventHttpRequest::CMD_GET, "/index.cphp");$base->loop();?>

以上例程的输出类似于:


_request_handler
Success: 200
Body:
PHP, date:
2013-03-13T20:27:52+05:00

Example #12 Connection listener based on a UNIX domain socket

<?php/* * Simple echo server based on libevent's connection listener. * * Usage: * 1) In one terminal window run: * * $ php unix-domain-listener.php [path-to-socket] * * 2) In another terminal window open up connection * to the socket, e.g.: * * $ socat - GOPEN:/tmp/1.sock * * 3) Start typing. The server should repeat the input. */class MyListenerConnection {    private $bev, $base;    public function __destruct() {        if ($this->bev) {            $this->bev->free();        }    }    public function __construct($base, $fd) {        $this->base = $base;        $this->bev = new EventBufferEvent($base, $fd, EventBufferEvent::OPT_CLOSE_ON_FREE);        $this->bev->setCallbacks(array($this, "echoReadCallback"), NULL,            array($this, "echoEventCallback"), NULL);        if (!$this->bev->enable(Event::READ)) {            echo "Failed to enable READ\n";            return;        }    }    public function echoReadCallback($bev, $ctx) {        // Copy all the data from the input buffer to the output buffer        $bev->output->addBuffer($bev->input);    }    public function echoEventCallback($bev, $events, $ctx) {        if ($events & EventBufferEvent::ERROR) {            echo "Error from bufferevent\n";        }        if ($events & (EventBufferEvent::EOF | EventBufferEvent::ERROR)) {            $bev->free();            $bev = NULL;        }    }}class MyListener {    public $base,        $listener,        $socket;    private $conn = array();    public function __destruct() {        foreach ($this->conn as &$c) $c = NULL;    }    public function __construct($sock_path) {        $this->base = new EventBase();        if (!$this->base) {            echo "Couldn't open event base";            exit(1);        }        if (file_exists($sock_path)) {            unlink($sock_path);        }         $this->listener = new EventListener($this->base,             array($this, "acceptConnCallback"), $this->base,             EventListener::OPT_CLOSE_ON_FREE | EventListener::OPT_REUSEABLE, -1,             "unix:$sock_path");        if (!$this->listener) {            trigger_error("Couldn't create listener", E_USER_ERROR);        }        $this->listener->setErrorCallback(array($this, "accept_error_cb"));    }    public function dispatch() {        $this->base->dispatch();    }    // This callback is invoked when there is data to read on $bev    public function acceptConnCallback($listener, $fd, $address, $ctx) {        // We got a new connection! Set up a bufferevent for it. */        $base = $this->base;        $this->conn[] = new MyListenerConnection($base, $fd);    }    public function accept_error_cb($listener, $ctx) {        $base = $this->base;        fprintf(STDERR, "Got an error %d (%s) on the listener. "            ."Shutting down.\n",            EventUtil::getLastSocketErrno(),            EventUtil::getLastSocketError());        $base->exit(NULL);    }}if ($argc <= 1) {    exit("Socket path is not provided\n");}$sock_path = $argv[1];$l = new MyListener($sock_path);$l->dispatch();?>

Example #13 Simple SMTP server

<?php /* * Author: Andrew Rose <hello at andrewrose dot co dot uk> * * Usage: * 1) Prepare cert.pem certificate and privkey.pem private key files. * 2) Launch the server script * 3) Open TLS connection, e.g.: *      $ openssl s_client -connect localhost:25 -starttls smtp -crlf * 4) Start testing the commands listed in `cmd` method below. */class Handler {    public $domainName = FALSE;    public $connections = [];    public $buffers = [];    public $maxRead = 256000;    public function __construct() {        $this->ctx = new EventSslContext(EventSslContext::SSLv3_SERVER_METHOD, [            EventSslContext::OPT_LOCAL_CERT  => 'cert.pem',            EventSslContext::OPT_LOCAL_PK    => 'privkey.pem',            //EventSslContext::OPT_PASSPHRASE  => ,            EventSslContext::OPT_VERIFY_PEER => false, // change to true with authentic cert            EventSslContext::OPT_ALLOW_SELF_SIGNED => true // change to false with authentic cert        ]);        $this->base = new EventBase();        if (!$this->base) {            exit("Couldn't open event base\n");        }        if (!$this->listener = new EventListener($this->base,            [$this, 'ev_accept'],            $this->ctx,            EventListener::OPT_CLOSE_ON_FREE | EventListener::OPT_REUSEABLE,            -1,            '0.0.0.0:25'))        {            exit("Couldn't create listener\n");        }        $this->listener->setErrorCallback([$this, 'ev_error']);        $this->base->dispatch();    }    public function ev_accept($listener, $fd, $address, $ctx) {        static $id = 0;        $id += 1;        $this->connections[$id]['clientData'] = ;        $this->connections[$id]['cnx'] = new EventBufferEvent($this->base, $fd,            EventBufferEvent::OPT_CLOSE_ON_FREE);        if (!$this->connections[$id]['cnx']) {            echo "Failed creating buffer\n";            $this->base->exit(NULL);            exit(1);        }        $this->connections[$id]['cnx']->setCallbacks([$this, "ev_read"], NULL,            [$this, 'ev_error'], $id);        $this->connections[$id]['cnx']->enable(Event::READ | Event::WRITE);        $this->ev_write($id, '220 '.$this->domainName." wazzzap?\r\n");    }    function ev_error($listener, $ctx) {        $errno = EventUtil::getLastSocketErrno();        fprintf(STDERR, "Got an error %d (%s) on the listener. Shutting down.\n",            $errno, EventUtil::getLastSocketError());        if ($errno != 0) {            $this->base->exit(NULL);            exit();        }    }    public function ev_close($id) {        $this->connections[$id]['cnx']->disable(Event::READ | Event::WRITE);        unset($this->connections[$id]);    }    protected function ev_write($id, $string) {        echo 'S('.$id.'): '.$string;        $this->connections[$id]['cnx']->write($string);    }    public function ev_read($buffer, $id) {        while($buffer->input->length > 0) {            $this->connections[$id]['clientData'] .= $buffer->input->read($this->maxRead);            $clientDataLen = strlen($this->connections[$id]['clientData']);            if($this->connections[$id]['clientData'][$clientDataLen-1] == "\n"                && $this->connections[$id]['clientData'][$clientDataLen-2] == "\r")            {                // remove the trailing \r\n                $line = substr($this->connections[$id]['clientData'], 0,                    strlen($this->connections[$id]['clientData']) - 2);                $this->connections[$id]['clientData'] = ;                $this->cmd($buffer, $id, $line);            }        }    }    protected function cmd($buffer, $id, $line) {        switch ($line) {            case strncmp('EHLO ', $line, 4):                $this->ev_write($id, "250-STARTTLS\r\n");                $this->ev_write($id, "250 OK ehlo\r\n");                break;            case strncmp('HELO ', $line, 4):                $this->ev_write($id, "250-STARTTLS\r\n");                $this->ev_write($id, "250 OK helo\r\n");                break;            case strncmp('QUIT', $line, 3):                $this->ev_write($id, "250 OK quit\r\n");                $this->ev_close($id);                break;            case strncmp('STARTTLS', $line, 3):                $this->ev_write($id, "220 Ready to start TLS\r\n");                $this->connections[$id]['cnx'] = EventBufferEvent::sslFilter($this->base,                    $this->connections[$id]['cnx'], $this->ctx,                    EventBufferEvent::SSL_ACCEPTING,                    EventBufferEvent::OPT_CLOSE_ON_FREE);                $this->connections[$id]['cnx']->setCallbacks([$this, "ev_read"], NULL, [$this, 'ev_error'], $id);                $this->connections[$id]['cnx']->enable(Event::READ | Event::WRITE);                break;            default:                echo 'unknown command: '.$line."\n";                break;        }    }}new Handler();