1.1.1. 调用流程

在 Run.ts 中调用 start 后,会先从容器中拿到 gateway 相关的配置,以及拿到之前在容器中绑定的 GatewayServer:

const configuration = this.container.get<GatewayConfig>(
  Types.gatewayConfig
);
this._server = this.container.get(GatewayServer);

然后调用 GatewayServer 中的 startServer 方法:

this._server.startServer();

在 startServer 方法中,实际上是为 Gateway 创建了一个 HTTP Server,并使用 this.handlerRequest 方法作为 requestListener:

this._server = http.createServer(async (req, res) =>
        this.handleRequest(req, res)
      );

在 handleRequest 这个 handleRequest 中,除了做一些为服务器响应设置头信息等事情以外,最核心的是调用了以下这行代码:

await this.routeIModelServerReq(req, res);

在 routeIModelServerReq 方法中,会根据客户端的请求 URL,判断应该将请求转发给哪一个服务

  • 如果 URL 是 iModelJs Backend 相关的,且 server.config.json 中 iModelJsBackends 为 true,则把请求转发给 IModelJsBackend 服务;

  • 如果 URL 是 licensing 相关的,则先进行权限验证 await this.authenticate(req, true),通过验证后再把请求转发给 Licensing 服务;

  • 如果 URL 不是 iModelJs Backend 或者 licensing 相关的,那么应该就是 Repositories 请求相关的,则先进行权限验证 await this.authenticate(req, true),通过验证后,执行 handleRepositoriesRequest 方法去处理请求:

    await this.handleRepositoriesRequest(
      this._routingParser.parseRepositoriesPath(pathname),
      req,
      res
    );
    

    客户端请求 Gateway 的 URL 一般格式为:

    http://gatewayUrl/:version/Repositories/:plugin--:location/:schemaName/:className
    

    举个例子,客户端请求创建新的 iModel,请求为:

    http://localhost:4000/sv1.1/Repositories/Context--b80917a4-36e1-4362-9cca-35b5c7c93bf6/ContextScope/iModel
    

    在 handleRepositoriesRequest 方法中,会根据 plugin 的值对请求进行不同的处理:

    • 如果 plugin 是 iModel,则调用 await this.forwardToIModelBank(req, res, reposQuery.location) 将请求转发到 iModelBank 服务;
    • 如果 plugin 是 Global 或者 Context,则调用 await this.forwardToLocalIModelManagerServer(req, res) 把请求转发到 iModelManager 服务中。

    在上面那个例子中,plugin 是 Context,所以此请求是被转发到 iModelManager 服务中。

1.1.2. 那么,我们是如何知道我们要转发请求的目的服务的 URL 是什么呢?

Orchestrator 服务是我们要启动的第一个服务,在启动 Orchestrator 服务的同时,会创建一个 Fastify 服务器(End Point),这个服务器设置了以下路由,用于处理 Orchestrator Client 发送过来的请求:

GET http://orchestrator.url/service/:serviceType/:instanceId
GET http://orchestrator.url/service/:serviceType
POST http://orchestrator.url/service/:serviceType
DELETE http://orchestrator.url/service/:serviceType/:instanceId
POST http://orchestrator.url/job/:jobType
POST http://orchestrator.url/shutdown

上面那个例子中,我们是将请求转发给 IModelMananger 服务的,我们要通过 Orchestrator Client 去对 Orchestrator 的 End Point 发起 GET 请求(GET service/imodel-manager),这个请求的响应就是 iModel Manager 服务,里面保存了 protocol、hostname、port、url、category、runnableType 和 instanceId 的信息,这里的 url 正是我们要转发的目的服务的 URL,然后通过 Proxy Server 把客户端的请求转发到目的服务上。

results matching ""

    No results matching ""