mirror of
https://github.com/danog/ext-uv.git
synced 2024-11-30 04:29:01 +01:00
add http server sample
This commit is contained in:
parent
c80410fb08
commit
db85553439
10
examples/debug_timer.php
Normal file
10
examples/debug_timer.php
Normal file
@ -0,0 +1,10 @@
|
||||
<?php
|
||||
$timer = uv_timer_init();
|
||||
|
||||
$stat = array();
|
||||
$stat['begin'] = memory_get_usage();
|
||||
|
||||
uv_timer_start($timer, 10, 1000, function($stat, $timer) use (&$stat){
|
||||
$stat["current"] = memory_get_usage();
|
||||
printf("memory: %d\n", $stat["current"] - $stat['begin']);
|
||||
});
|
140
examples/http.php
Normal file
140
examples/http.php
Normal file
@ -0,0 +1,140 @@
|
||||
<?php
|
||||
/**
|
||||
* TODO: this implementation is not correct some error handling.
|
||||
*/
|
||||
|
||||
function createServer(Closure $closure)
|
||||
{
|
||||
$server = new HttpServer();
|
||||
$server->addListener($closure);
|
||||
|
||||
return $server;
|
||||
}
|
||||
|
||||
class HttpResponse
|
||||
{
|
||||
protected $server;
|
||||
protected $client;
|
||||
|
||||
protected $code = 200;
|
||||
protected $headers = array();
|
||||
protected $body = array();
|
||||
protected $http_version = "1.0";
|
||||
|
||||
public function __construct($server, $client)
|
||||
{
|
||||
$this->server = $server;
|
||||
$this->client = $client;
|
||||
}
|
||||
|
||||
public function writeHead($code, array $headers)
|
||||
{
|
||||
$this->code = $code;
|
||||
$this->headers = $headers;
|
||||
}
|
||||
|
||||
public function write($data)
|
||||
{
|
||||
$this->body[] = $data;
|
||||
}
|
||||
|
||||
public function end()
|
||||
{
|
||||
// Todo: implement correctly
|
||||
$buffer = "HTTP/1.0 200 OK\r\n";
|
||||
foreach ($this->headers as $key => $value) {
|
||||
$buffer .= $key . ": " . $value . "\r\n";
|
||||
}
|
||||
$buffer .= "\r\n";
|
||||
$buffer .= join("", $this->body);
|
||||
|
||||
uv_write($this->client, $buffer, array($this->server, "onWrite"));
|
||||
}
|
||||
}
|
||||
|
||||
class HttpServer
|
||||
{
|
||||
protected $server;
|
||||
|
||||
protected $clients = array();
|
||||
protected $parsers = array();
|
||||
protected $closure;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->server = uv_tcp_init();
|
||||
}
|
||||
|
||||
public function addListener($closure)
|
||||
{
|
||||
$this->closure = $closure;
|
||||
}
|
||||
|
||||
public function onShutdown($handle)
|
||||
{
|
||||
uv_close($handle, array($this, "onClose"));
|
||||
}
|
||||
|
||||
public function onClose($handle)
|
||||
{
|
||||
unset($this->clients[(int)$handle]);
|
||||
unset($this->parsers[(int)$handle]);
|
||||
|
||||
}
|
||||
|
||||
public function onWrite($status, $client)
|
||||
{
|
||||
if ($status == 0) {
|
||||
uv_shutdown($client, array($this, "onShutdown"));
|
||||
} else {
|
||||
echo "[write_failed]";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function onRead($client, $buffer, $nread)
|
||||
{
|
||||
//echo $buffer;
|
||||
//echo "--Error: " . uv_err_name(uv_last_error(uv_default_loop())) . PHP_EOL;
|
||||
|
||||
if ($nread < 0) {
|
||||
//echo "[NREAD={$nread}]\n";
|
||||
uv_shutdown($client, array($this, "onShutdown"));
|
||||
} else if ($nread == 0) {
|
||||
// nothing to do.
|
||||
//echo "[NREAD=0]\n";
|
||||
} else {
|
||||
$result = array();
|
||||
|
||||
if (uv_http_parser_execute($this->parsers[(int)($client)], $buffer, $result)){
|
||||
$response = new HttpResponse($this, $client);
|
||||
|
||||
$closure = $this->closure;
|
||||
$closure($result, $response);
|
||||
} else {
|
||||
// nothing to do. (waiting next buffer)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function onConnect($server)
|
||||
{
|
||||
$client = uv_tcp_init();
|
||||
uv_tcp_nodelay($client, 1);
|
||||
uv_accept($server,$client);
|
||||
|
||||
$this->clients[(int)$client] = $client;
|
||||
$this->parsers[(int)($client)] = uv_http_parser_init();
|
||||
|
||||
uv_read_start($client, array($this, "onRead"));
|
||||
}
|
||||
|
||||
public function listen($port)
|
||||
{
|
||||
uv_tcp_nodelay($this->server, 1);
|
||||
uv_tcp_bind6($this->server, uv_ip6_addr("::1",$port));
|
||||
uv_listen($this->server, 511, array($this, "onConnect"));
|
||||
|
||||
uv_run(uv_default_loop());
|
||||
}
|
||||
}
|
@ -1,114 +1,9 @@
|
||||
<?php
|
||||
/* do we need these function ? */
|
||||
ob_implicit_flush(true);
|
||||
ob_end_flush();
|
||||
require "http.php";
|
||||
require "debug_timer.php";
|
||||
|
||||
|
||||
global $servers;
|
||||
|
||||
$servers = 0;
|
||||
$timer = uv_timer_init();
|
||||
$stat = array();
|
||||
$stat['begin'] = memory_get_usage();
|
||||
|
||||
uv_timer_start($timer, 10, 1000, function($stat, $timer) use (&$stat){
|
||||
global $servers;
|
||||
$stat["current"] = memory_get_usage();
|
||||
printf("memory: %d\n", $stat["current"] - $stat['begin']);
|
||||
printf("servers: %d\n", $servers);
|
||||
});
|
||||
|
||||
|
||||
$server = uv_tcp_init();
|
||||
uv_tcp_bind6($server,uv_ip6_addr("::1",8888));
|
||||
uv_tcp_nodelay($server, 1);
|
||||
|
||||
function on_connect($server)
|
||||
{
|
||||
global $servers;
|
||||
global $parsers;
|
||||
|
||||
echo "[LISTEN]" . PHP_EOL;
|
||||
$client = uv_tcp_init();
|
||||
uv_tcp_nodelay($client, 1);
|
||||
uv_accept($server,$client);
|
||||
$servers++;
|
||||
echo "-Error: " . uv_err_name(uv_last_error(uv_default_loop())) . PHP_EOL;
|
||||
|
||||
echo "[Accept]" . PHP_EOL;
|
||||
$parsers[(int)($client)] = uv_http_parser_init();
|
||||
|
||||
uv_read_start($client, "on_read");
|
||||
}
|
||||
|
||||
|
||||
function on_read($client, $buffer, $nread)
|
||||
{
|
||||
//echo $buffer;
|
||||
echo "--Error: " . uv_err_name(uv_last_error(uv_default_loop())) . PHP_EOL;
|
||||
|
||||
global $parsers;
|
||||
if ($nread < 0) {
|
||||
echo "[NREAD={$nread}]\n";
|
||||
uv_shutdown($client, "on_shutdown");
|
||||
} else if ($nread == 0) {
|
||||
// nothing to do.
|
||||
echo "[NREAD=0]\n";
|
||||
} else {
|
||||
$result = array();
|
||||
echo "parser" . PHP_EOL;
|
||||
if (uv_http_parser_execute($parsers[(int)($client)], $buffer, $result)){
|
||||
echo $buffer;
|
||||
echo PHP_EOL;
|
||||
$response = "HTTP/1.0 200 OK
|
||||
Pragma: no-cache
|
||||
Accept-Ranges: bytes
|
||||
Content-Length: 6
|
||||
Connection: close
|
||||
Content-Type: text/html
|
||||
|
||||
Hello
|
||||
";
|
||||
echo $response;
|
||||
uv_write($client,$response,"on_write");
|
||||
} else {
|
||||
// nothing todo. (waiting next buffer)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function on_shutdown($handle)
|
||||
{
|
||||
global $parsers;
|
||||
global $servers;
|
||||
$servers--;
|
||||
unset($parsers[(int)$handle]);
|
||||
echo "shutdown" . PHP_EOL;
|
||||
|
||||
uv_close($handle, function($handle){
|
||||
echo "=close\n";
|
||||
});
|
||||
}
|
||||
|
||||
function on_shutdown2($handle)
|
||||
{
|
||||
uv_close($handle,function($handle){echo "==close\n";});
|
||||
}
|
||||
|
||||
function on_write($status, $client)
|
||||
{
|
||||
global $servers;
|
||||
global $parsers;
|
||||
$servers--;
|
||||
|
||||
unset($parsers[(int)$client]);
|
||||
if ($status == 0) {
|
||||
uv_shutdown($client, "on_shutdown2");
|
||||
} else {
|
||||
echo "[write_failed]";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uv_listen($server, 127, "on_connect");
|
||||
uv_run();
|
||||
createServer(function($request, $response){
|
||||
$response->writeHead(200, array("Content-Type" => "text/plain"));
|
||||
$response->write("Hello World");
|
||||
$response->end();
|
||||
})->listen(8888);
|
||||
|
Loading…
Reference in New Issue
Block a user