Beispiele

Beispiel #1 Simple HTTP client

<?php
// Read callback
function readcb($bev$base) {
    
//$input = $bev->input; //$bev->getInput();

    //$pos = $input->search("TTP");
    
$pos $bev->input->search("TTP");

    while ((
$n $bev->input->remove($buf1024)) > 0) {
        echo 
$buf;
    }
}

// Event callback
function 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 <<<EOS
Trivial HTTP 0.x client
Syntax: php 
{$argv[0]} [hostname] [resource]
Example: php 
{$argv[0]} www.google.com /

EOS;
    exit();
}

$base = new EventBase();

$dns_base = new EventDnsBase($baseTRUE); // We'll use async DNS resolving
if (!$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], 80EventUtil::AF_UNSPEC)) {
    exit(
"Can't connect to host {$argv[1]}\n");
}

$base->dispatch();
?>

Das oben gezeigte Beispiel erzeugt eine ähnliche Ausgabe wie:

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

Beispiel #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 callback
function readcb($bev$base) {
    
$input $bev->getInput();

    while ((
$n $input->remove($buf1024)) > 0) {
        echo 
$buf;
    }
}

// Event callback
function 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();
?>

Beispiel #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$fdEventBufferEvent::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 <= || $port 65535) {
    exit(
"Invalid port");
}

$l = new MyListener($port);
$l->dispatch();
?>

Beispiel #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_ACCEPTINGEventBufferEvent::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 <= || $port 65535) {
    exit(
"Invalid port\n");
}


$l = new MySslEchoServer($port);
$l->dispatch();
?>

Beispiel #5 Signal handler

<?php
/*
Launch it in a terminal window:

$ php examples/signal.php

In another terminal window find out the pid and send SIGTERM, e.g.:

$ ps aux | grep examp
ruslan    3976  0.2  0.0 139896 11256 pts/1    S+   10:25   0:00 php examples/signal.php
ruslan    3978  0.0  0.0   9572   864 pts/2    S+   10:26   0:00 grep --color=auto examp
$ kill -TERM 3976

At 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);
?>

Beispiel #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($dir0750EIO_PRI_DEFAULT"my_nop_cb");

$event = new Event($baseeio_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";
?>

Beispiel #7 Miscellaneous

<?php
/* {{{ Config & supported stuff */
echo "Supported methods:\n";
foreach (
Event::getSupportedMethods() as $m) {
    echo 
$mPHP_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 feature
if ($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");
}
/* }}} */

/* {{{ Base */
$base = new EventBase();
$event = new Event($baseSTDINEvent::READ 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 }}} */
?>

Beispiel #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 
$sPHP_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 <= || $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(48));
$http->setCallback("/about""_http_about");
$http->setDefaultCallback("_http_default""custom data value");

$http->bind("0.0.0.0"8010);
$base->loop();
?>

Das oben gezeigte Beispiel erzeugt eine ähnliche Ausgabe wie:

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

Beispiel #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 <= || $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(48));
$http->setCallback("/about""_http_about");
$http->setCallback("/err400""_http_400");
$http->setDefaultCallback("_http_default""custom data value");

$http->bind($ip$port);
$base->dispatch();

Beispiel #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 
$sPHP_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 <= || $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($baseNULL$host$port$ctx);
$conn->setTimeout(50);

$req = new EventHttpRequest("_request_handler"$base);
$req->addHeader("Host"$hostEventHttpRequest::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($reqEventHttpRequest::CMD_POST"/dump");

$base->dispatch();
echo 
"END\n";
?>

Beispiel #11 EventHttpConnection::makeRequest() example

<?php
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 
$sPHP_EOL;
            }
        }
    }

    
$base->exit(NULL);
}

$address "127.0.0.1";
$port 80;

$base = new EventBase();
$conn = new EventHttpConnection($baseNULL$address$port);
$conn->setTimeout(5);
$req = new EventHttpRequest("_request_handler"$base);

$req->addHeader("Host"$addressEventHttpRequest::OUTPUT_HEADER);
$req->addHeader("Content-Length""0"EventHttpRequest::OUTPUT_HEADER);
$conn->makeRequest($reqEventHttpRequest::CMD_GET"/index.cphp");

$base->loop();
?>

Das oben gezeigte Beispiel erzeugt eine ähnliche Ausgabe wie:

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

Beispiel #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$fdEventBufferEvent::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();
?>

Beispiel #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",
            
$errnoEventUtil::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 '$line4):
                
$this->ev_write($id"250-STARTTLS\r\n");
                
$this->ev_write($id"250 OK ehlo\r\n");
                break;

            case 
strncmp('HELO '$line4):
                
$this->ev_write($id"250-STARTTLS\r\n");
                
$this->ev_write($id"250 OK helo\r\n");
                break;

            case 
strncmp('QUIT'$line3):
                
$this->ev_write($id"250 OK quit\r\n");
                
$this->ev_close($id);
                break;

            case 
strncmp('STARTTLS'$line3):
                
$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();

Hier Kannst Du einen Kommentar verfassen


Bitte gib mindestens 10 Zeichen ein.
Wird geladen... Bitte warte.
* Pflichtangabe
Es sind noch keine Kommentare vorhanden.

PHP cURL-Tutorial: Verwendung von cURL zum Durchführen von HTTP-Anfragen

cURL ist eine leistungsstarke PHP-Erweiterung, die es Ihnen ermöglicht, mit verschiedenen Servern über verschiedene Protokolle wie HTTP, HTTPS, FTP und mehr zu kommunizieren. ...

TheMax

Autor : TheMax
Kategorie: PHP-Tutorials

Midjourney Tutorial - Anleitung für Anfänger

Über Midjourney, dem Tool zur Erstellung digitaler Bilder mithilfe von künstlicher Intelligenz, gibt es ein informatives Video mit dem Titel "Midjourney Tutorial auf Deutsch - Anleitung für Anfänger" ...

Mike94

Autor : Mike94
Kategorie: KI Tutorials

Grundlagen von Views in MySQL

Views in einer MySQL-Datenbank bieten die Möglichkeit, eine virtuelle Tabelle basierend auf dem Ergebnis einer SQL-Abfrage zu erstellen. ...

admin

Autor : admin
Kategorie: mySQL-Tutorials

Tutorial veröffentlichen

Tutorial veröffentlichen

Teile Dein Wissen mit anderen Entwicklern weltweit

Du bist Profi in deinem Bereich und möchtest dein Wissen teilen, dann melde dich jetzt an und teile es mit unserer PHP-Community

mehr erfahren

Tutorial veröffentlichen

Notizen-App: was ist eure - ich komm immer wieder auf Keep zurück...

Hallo liebe Community, guten Abend, Notizen-App: was ist eure - ich komm immer wieder auf Keep zurück... was ist eure beste NoteTaking App!? i ...

Geschrieben von dhubs am 22.12.2024 23:05:11
Forum: Off-Topic Diskussionen
How to overcome Safari's iframe cookie block?

To overcome Safari's iframe cookie block, you can use the SameSite=None; Secure cookie attribute in conjunction with a third-party domain that sup ...

Geschrieben von Joniemartinez am 21.12.2024 13:28:24
Forum: HTML, JavaScript, AJAX, jQuery, CSS, Bootstrap, LESS
Probleme mit speichern in Datenbank in französisch

Les erreurs fréquentes lors de l'enregistrement de données dans une base de données incluent des problèmes de connexion, des erreurs de syntax ...

Geschrieben von Alice12 am 18.12.2024 05:07:21
Forum: PHP Developer Forum
Gibt es eine API zum Abrufen von PHP-Code-Referenzen?

PHP.net bietet eine umfassende Online-Dokumentation für PHP. Es gibt keine offizielle API zum Abrufen von PHP-Dokumentationen direkt, aber du kan ...

Geschrieben von Alice12 am 18.12.2024 05:03:27
Forum: PHP Developer Forum