Swoole 使用 TCP 协议实现简单的 HTTP 服务

HTTP 协议的响应包括响应头和响应体(不是必须的),响应头中的 Content-Length 用来标记响应 Body 的长度,这其实是 HTTP 协议的分包机制。假设实际发送的 Body 长度小于 Content-Length,浏览器会一直处于等待接收数据的状态(小圈一直转)。假设实际发送的 Body 长度大于 Content-Length,多于的部分会被丢弃。


Swoole\Coroutine\run(function () {

    $server = new Swoole\Coroutine\Server('127.0.0.1', '9501', false, true);

    $server->handle(function (Swoole\Coroutine\Server\Connection $conn) {
        while (true) {
            $data = $conn->recv();
            if (empty($data)) {
                $conn->close();
                break;
            }

            $response = new Response();

            $response->withHeader('Content-Type', 'text/html;charset=utf-8')
                ->withHeader('Content-Length', '4')
                ->withBody('abc');

            // 报头标记了 4 个字节的 body, 实际发送了 3 个字节,此时浏览器在转圈
            $conn->send($response->getPackage());

            // 10 秒后发送最后一个字节,所有数据发送完毕
            Swoole\Coroutine::sleep(10);
            $conn->send('d');

        }
    });


    $server->start();

});


/**
 * 用来简单组装 header 和 body
 * Class Response
 */
class Response {

    private $header = "HTTP/1.1 200 OK\r\n";
    private $body = '';

    public function withHeader($name, $value) {
        $name = strtolower($name);
        if ($name == 'content-type') {
            $this->header .= "Content-Type: {$value}\r\n";
        } elseif ($name == 'content-length') {
            $this->header .= "Content-Length: " . $value . "\r\n";
        }
        return $this;
    }

    public function withBody($body) {
        $this->body .= $body;
        return $this;
    }

    /**
     * 获取组装好的 http 报文
     * @return string
     */
    public function getPackage() {
        return $this->header ."\r\n" . $this->body;
    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值