zoukankan      html  css  js  c++  java
  • hyperf json-rpc剖析

    hyperf在启动阶段BootApplication会初始化JsonRpc中的TcpServer文件构造函数,而TcpServer文件继承了RpcServer的Server文件。
    通过这两个文件的构造函数,将自动注入ContainerInterface、DispatcherInterface、ExceptionHandlerDispatcher、LoggerInterface
    然后初始化initServerConfig、initProtocol及RpcServer的Server文件的initCoreMiddleware方法。
    RpcServer的Server文件下有个createCoreMiddleware抽象方法,它的实现是在JsonRpc中的TcpServer文件中。
    createCoreMiddleware方法下new了一个JsonRpc下的CoreMiddleware文件
    CoreMiddleware文件继承了RpcServer下的CoreMiddleware文件,它又继承了HttpServer下的CoreMiddleware文件
    在HttpServer下的CoreMiddleware的构造函数中,使用了$this->createDispatcher($serverName);它调用的不是这个函数自身的createDispatcher方法,而是子类RpcServer下的CoreMiddleware文件的createDispatcher方法。
    调用顺序:https://www.cnblogs.com/cnlihao/p/14172665.html
    createDispatcher中make了一个RpcServer下DispatcherFactory类,并将pathGenerator带入,然后从注解中和配置中取得路由信息。
    注解中获取路由信息要使用PathGenerator文件的generate方法,将服务注解转化为路由地址。
    例如:

    <?php
    
    namespace AppJsonRpc;
    
    use HyperfRpcServerAnnotationRpcService;
    
    /**
     * 注意,如希望通过服务中心来管理服务,需在注解内增加 publishTo 属性
     * @RpcService(name="CalculatorService", protocol="jsonrpc-http", server="jsonrpc-http")
     */
    class CalculatorService implements CalculatorServiceInterface
    {
        // 实现一个加法方法,这里简单的认为参数都是 int 类型
        public function add(int $a, int $b): int
        {
            // 这里是服务方法的具体实现
            return $a + $b;
        }
    }
    

    他的路由就是/calculator/add
    初始化完毕后,当我们有消息过来时,我们会调用RpcServer的Server文件中onReceive方法。【JsonRpc中的TcpServer文件继承了RpcServer的Server,所以虽然从服务器配置文件中看是JsonRpc中的TcpServer文件,但实际调用了RpcServer的Server文件中onReceive方法】
    然后从JsonRpc中的TcpServer文件buildJsonRpcRequest方法中解析请求。其中它使用了一个ServerManager::get($this->serverName)方法来获取tcp服务。
    将请求信息根据之前注册的协议解码后传递个请求信息构造函数buildJsonRpcRequest。【只是很简单的将json转为了数组】

    {"jsonrpc":"2.0","method":"/calculator/add","params":{"a":1,"b":2},"id":"5fe197e648a5c","context":[]}
    

    将请求信息构造成一个符合Psr7Request的请求信息,然后放入上下文中。
    造成一个符合Psr7Response的响应信息,然后放入上下文中。
    onReceive方法中依次又调用了中间件dispatch方法,最后继承的是HttpServer下的CoreMiddleware文件的dispatch方法。方法中的dispatch方法是FastRouteDispatcherGroupCountBased这里的dispatch方法。这个方法将一些中间件信息放入了上下文.
    下一步,调用了dispatcher类中的dispatch方法,也就是RpcServer下RequestDispatcher文件的dispatch方法
    进一步调用了Dispatcher组件中HttpRequestHandler文件下handle方法。他又调用了继承的AbstractRequestHandler文件中handleRequest方法。
    在handleRequest方法中直接使用核心处理器,或从容器获取处理器,调用process方法。这里使用的是coreMiddleware类。
    也就是HttpServer下的CoreMiddleware文件的process方法。
    process方法下可以使用handleFound方法,这里handleFound方法使用的是JsonRpc中CoreMiddleware下的方法而不是HttpServer中的。
    调用顺序:https://www.cnblogs.com/cnlihao/p/14172665.html
    在handleFound方法使用容器获取相关的类,例如:AppJsonRpcCalculatorService
    然后处理参数,调用相关的方法。
    最后将数据返回。
    通过JsonRpc中ResponseBuilder下buildResponse方法处理数据,接着调用formatResponse方法,接着调用JsonRpc下DataFormatter中formatResponse方法。【头文件】
    接着JsonEofPacker去将数据编码,最后将编码后的数据通过swoole tcp发给调用端。

  • 相关阅读:
    spring整合freemarker 自定义标签
    curl 取不到第二个参数解决方法
    solr5.5教程-solr.home 配置
    solr5.5教程-schema.xml部分配置
    solr5.5教程-solrconfig.xml,加载schema.xml
    solr5.5教程-tomcat布署(2)
    solr5.5教程-tomcat布署
    jsp页面el表达式不起作用
    spring+hibernate--直接修改数据库,再通过hibernate查询数据不变
    13 hbase连接
  • 原文地址:https://www.cnblogs.com/cnlihao/p/14171909.html
Copyright © 2011-2022 走看看