Hyper中的 Request和Response

Posted bobobobobo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Hyper中的 Request和Response相关的知识,希望对你有一定的参考价值。

常见的Request和Response

请求相关

use PsrHttpMessageRequestInterface;
use PsrHttpMessageServerRequestInterface;
use HyperfHttpMessageBaseRequest;
use HyperfHttpMessageServerRequest;
use HyperfHttpServerContractRequestInterface ;
use HyperfHttpServerRequest;
use SwooleHttpRequest;
use SwooleHttp2Request;

响应相关

use PsrHttpMessageResponseInterface;
use HyperfHttpMessageBaseResponse;
use HyperfHttpMessageServerResponse;
use HyperfHttpServerContractResponseInterface;
use HyperfHttpServerResponse;
use SwooleHttpResponse;
use SwooleHttp2Response;

其中

use SwooleHttpRequest;
use SwooleHttp2Request;

use SwooleHttpResponse;
use SwooleHttp2Response;

是Swoole提供的请求响应对象,主要是为Hyperf构建标准的PSR7 Request和Response对象提供元数据,我们不多做解释,平时框架里不直接使用

 

请求

PsrHttpMessageRequestInterface和PsrHttpMessageServerRequestInterface

这两个接口是PSR7协议定义的关于HTTP消息对象的一些推荐规范的接口
ServerRequestInterface 是 RequestInterface 的一个子接口
RequestInterface是抽象概念上的请求接口
ServerRequestInterface是专属于服务端的请求接口
Hyperf 的请求对象是基于PSR7实现的,也就是说hyperf里的Request对象都是
ServerRequestInterface和RequestInterface的实现类
(HyperfHttpMessageBaseRequest 和 HyperfHttpMessageServerRequest)

HyperfHttpMessageBaseRequest和HyperfHttpMessageServerRequest

HyperfHttpMessageBaseRequest是PsrHttpMessageRequestInterface的实现
HyperfHttpMessageServerRequest 是 PsrHttpMessageServerRequestInterface的实现
也就是说HyperfHttpServerRequest是由HyperfHttpMessageBaseRequest构建来的

HyperfHttpServerContractRequestInterface和HyperfHttpServerRequest

HyperfHttpServerRequest是HyperfHttpServerContractRequestInterface的实现类

 

Hyperf是一个协程框架,而Hyperf里面DI容器管理的对象都是长生命周期的对象。
假设我们再Hyperf里的一个Controller里使用了一个Request对象,而一个Request对象他跟随的就是一个请求。
一个请求就是一个协程,而这个Controller是会在多个协程之间来回切换混着使用的。
所以假设我们将一个Request对象绑定在这个Controller的一个成员属性上,就非常容易出现协程间数据混淆的问题。
因此Hyperf提供了HyperfHttpServerContractRequestInterface,其目的在于保持在Controller的成员属性上
直接Inject注入的这种用法同时又不会导致协程间的数据混淆。

实现方式:
HyperfHttpServerRequest核心代码

public function query(?string $key = null, $default = null)
{
    if ($key === null) {
        return $this->getQueryParams();
    }
    return data_get($this->getQueryParams(), $key, $default);
}

public function getQueryParams()
{
    return $this->call(__FUNCTION__, func_get_args());
}


protected function call($name, $arguments)
{
    $request = $this->getRequest();
    if (! method_exists($request, $name)) {
        throw new RuntimeException(‘Method not exist.‘);
    }
    return $request->{$name}(...$arguments);
}

protected function getRequest(): ServerRequestInterface
{
    return Context::get(ServerRequestInterface::class);
}

getRequest()方法返回的 Request对象是一个代理类,它代理的是ServerRequestInterface的储存对象也就是HyperfHttpServerRequest对象

HyperfHttpServerRequest是一个标准的PSR7实现类,也绑定着每一次的用户请求,也就是说HyperfHttpServerRequest是绝对不能再协程之间相互引用的。

它必须通过协程上下文来取得对应的Request对象。

HyperfHttpServerRequest帮助我们则很好地帮我们解决了这个问题,我们可以只需使用HyperfHttpServerRequest对象,由框架底层自动完成请求对象的选择。

我们要获HyperfHttpServerRequest对象,就必须Inject HyperfHttpServerContractRequestInterface来得到这个代理对象

 

响应

PsrHttpMessageResponseInterface

PSR7约束的响应接口

HyperfHttpMessageBaseResponse

基于PSR7约束实现的响应对象,里面包含了Response的标准实现

HyperfHttpMessageServerResponse

是HyperfHttpMessageBaseResponse的一个子类

它的主要目的是在服务端的情况下,将当前构建好的Response对象里面的内容响应给当前的请求

其中HyperfHttpMessageServerResponse 下的send方法

将当前构建好的Response对象通过Swoole的Response对象将这些内容返回给这个请求

换句话说HyperfHttpMessageServerResponse,就是SwooleHttpResponse与HyperfHttpMessageBaseResponse的一个桥接,来完成这个请求的响应

类似于HyperfHttpMessageServerRequest 也是从协程上下文中获取对应的响应对象,并做相关的操作

HyperfHttpMessageServerResponse处理提供PSR7约束的方法之外,还提供了一些日常开发中常用的结果响应的方法

HyperfHttpServerContractResponseInterface

请求的代理类

HyperfHttpServerResponse

HyperfHttpServerContractResponseInterface的实现

实现方式类似

 

总结

请求:

存储在协程上下文中的请求对象的key是PsrHttpMessageServerRequestInterface

对应的储存在协程上下文中的对象是HyperfHttpMessageServerRequest

在日常开发中使用的,注入的是HyperfHttpServerContractRequestInterface接口类

HyperfHttpServerContractRequestInterface实际的代理对象就是HyperfHttpServerRequest

 

响应相关类似请求

 

以上是关于Hyper中的 Request和Response的主要内容,如果未能解决你的问题,请参考以下文章

错误记录Android Studio 配置 GitHub 报错 ( Can‘t login using given credentials: Request response: 401 Una )(代

Java 中的 request 和response 理解

Django中的Request和Response

Django中的Request和Response

是否应在 Hyper-V 中创建第 1 代或第 2 代虚拟机?

Java 中的 request 和response 区别