Repository navigation
Expand file tree
/
Copy pathhttp2-server.php
More file actions
87 lines (73 loc) · 2.46 KB
/
Copy pathhttp2-server.php
File metadata and controls
87 lines (73 loc) · 2.46 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
<?php
declare(strict_types=1);
/**
* HTTP/2 Server 示例 — 基于 Workerman
*
* 使用方式:
* php examples/http2-server.php start
*
* 测试(需要 h2c 客户端,如 curl --http2-prior-knowledge):
* curl --http2-prior-knowledge -v http://127.0.0.1:8080/
*/
require_once __DIR__ . '/../vendor/autoload.php';
use Protocols\Http2;
use Workerman\Connection\ConnectionInterface;
use Workerman\Worker;
$worker = new Worker('http2://0.0.0.0:8080');
// ---- TCP 连接建立 ----
$worker->onConnect = function (ConnectionInterface $connection) {
echo "[connect] client connected\n";
Http2::initConnection($connection);
};
// ---- TCP 连接关闭 ----
$worker->onClose = function (ConnectionInterface $connection) {
echo "[close] client disconnected\n";
Http2::destroyConnection($connection);
};
// ---- HTTP/2 请求到达 ----
// decode() 返回完整请求时触发,$request 格式:
// ['stream_id' => int, 'stream' => Stream, 'headers' => list<array{string,string}>, 'body' => string]
$worker->onMessage = function (ConnectionInterface $connection, $request) {
$streamId = $request['stream_id'];
$headers = $request['headers'];
$body = $request['body'];
// 提取伪头部
$method = 'GET';
$path = '/';
foreach ($headers as [$name, $value]) {
if ($name === ':method') $method = $value;
if ($name === ':path') $path = $value;
}
echo "[request] stream={$streamId} {$method} {$path} body_len=" . strlen($body) . "\n";
// ---- 业务逻辑 ----
if ($path === '/') {
$html = '<h1>HTTP/2 Server</h1><p>Hello from Workerman!</p>';
$connection->send([
'stream_id' => $streamId,
':status' => '200',
'headers' => [
'content-type' => 'text/html; charset=utf-8',
'content-length' => (string)strlen($html),
],
'body' => $html,
]);
return;
}
if ($path === '/api') {
$connection->send([
'stream_id' => $streamId,
':status' => '200',
'headers' => ['content-type' => 'application/json'],
'body' => json_encode(['method' => $method, 'path' => $path]),
]);
return;
}
// 404
$connection->send([
'stream_id' => $streamId,
':status' => '404',
'headers' => ['content-type' => 'text/plain'],
'body' => 'Not Found',
]);
};
Worker::runAll();