🐈
【PHP】AMPHP の Socket クラスで HTTP/1 サーバーをつくる
まず Composer でダウンロードする
composer require amphp/socket
次のコードを用意する
server.php
<?php
// https://github.com/amphp/socket/blob/58e0422221825b79681b72c50c47a930be7bf1e1/examples/simple-http-server.php
use Amp\Socket;
use function Amp\async;
require __DIR__ . '/vendor/autoload.php';
$server = Socket\listen('0.0.0.0:8000');
echo 'Listening for new connections on ' . $server->getAddress() . ' ...' . PHP_EOL;
echo 'Open your browser and visit http://' . $server->getAddress() . '/' . PHP_EOL;
while ($socket = $server->accept()) {
async(function () use ($socket) {
$address = $socket->getRemoteAddress();
assert($address instanceof Socket\InternetAddress);
$ip = $address->getAddress();
$port = $address->getPort();
echo "Accepted connection from {$address}." . PHP_EOL;
$body = "Hey, your IP is {$ip} and your local port used is {$port}.";
$bodyLength = strlen($body);
$socket->write("HTTP/1.1 200 OK\r\nConnection: close\r\nContent-Length: {$bodyLength}\r\n\r\n{$body}");
$socket->end();
});
}
スクリプトを実行して HTTP/1 サーバーを起動させる
php server.php
http://localhost:8000
にアクセスするとレスポンスが表示される
Listening for new connections on 0.0.0.0:8000 ...
Open your browser and visit https://0.0.0.0:8000/
Accepted connection from 127.0.0.1:36878.
Accepted connection from 127.0.0.1:36884.
Accepted connection from 127.0.0.1:35510.
Accepted connection from 127.0.0.1:35526.
ほかに TLS 対応を試してみたが curl ではレスポンスが返ってくるものの Chrome ブラウザーではクラッシュしてしまった
$cert = new Socket\Certificate(
'localhost.pem',
'localhost-key.pem'
);
$context = (new Socket\BindContext)
->withTlsContext(
(new Socket\ServerTlsContext)->withDefaultCertificate($cert)
);
$server = Socket\listen('0.0.0.0:8000', $context);
while ($socket = $server->accept()) {
async(function () use ($socket) {
$socket->setupTls();
}
}
Discussion