BaseService.php 4.0 KB
<?php

namespace AukeySwrpc;


use AukeySwrpc\Request\SyncRequest;
use AukeySwrpc\Tracer\TracerContext;

/**
 * Class BaseService
 *
 * @package App\Clients
 * @author pengjch 2024314 11:26:45
 */
class BaseService
{
    protected $serviceKey;
    protected $traceContext = null;

    /**
     * @return static
     * @author 2021-03-14 11:25:18
     */
    public static function factory()
    {
        return new static();
    }

    /**
     * BaseService constructor.
     */
    public function __construct()
    {
        $this->init();
    }

    /**
     * @author pengjch 2024314 11:33:22
     */
    protected function init()
    {
    }

    /**
     * @param $serviceKey
     * @author pengjch 2024314 11:31:57
     */
    protected function setService($serviceKey)
    {
        $this->serviceKey = $serviceKey;
    }

    /**
     * 链路追踪上下文
     *
     * @param TracerContext|null $context
     * @return $this
     * @author pengjch 2024314 11:27:45
     */
    public function trace(?TracerContext $context = null)
    {
        $this->traceContext = $context;
        return $this;
    }

    /**
     * 调用远程服务
     *
     * @param $method
     * @param $args
     * @return mixed
     * @throws \Exception
     * @author pengjch 2024-03-14 11:25:18
     */
    protected function callRemoteService($method, $args)
    {
        $serviceNs = $this->getTargetServiceNamespace();
        $method = $serviceNs . '_' . $method;
        $client = ClientManger::getInstance($this->serviceKey);
        $request = SyncRequest::create($method, $args, $this->traceContext);
        return $client->send($request);
    }

    /**
     * 调用本地服务
     *
     * @param $method
     * @param $args
     * @return string
     * @author pengjch 2024-03-14 11:25:18
     */
    protected function callLocalService($method, $args)
    {
        $serviceNs = $this->getTargetServiceNamespace();
        return call_user_func_array([$serviceNs::factory(), $method], $args);
    }

    /**
     * 获取目标调用类命名空间
     *
     * @return string
     * @author pengjch 2024314 12:6:8
     */
    protected function getTargetServiceNamespace(): string
    {
        $moduleName = $this->extractModuleName();
        /** @var \Nwidart\Modules\Laravel\Module $module */
//        $loader = require base_path('vendor').'/autoload.php';
//        // 获取注册的命名空间前缀并筛选出 Composer 包的命名空间
//        $prefixes = $loader->getPrefixesPsr4();
//        foreach ($prefixes as $key => $prefix) {
//            if($moduleName.'\\' === $key){
//
//            }
//        }
//        $moduleNs = ltrim(str_replace([base_path(), '/'], ['', '\\'], $module->getPath()), '\\');
        return $moduleName . '\\Http\\Service\\' . $this->extractServiceName();
    }

    /**
     * 根据调用类提前模块名称
     *
     * @return false|string
     * @author pengjch 2024314 12:0:17
     */
    protected function extractModuleName()
    {
        $calledClass = get_called_class();
        $module = str_replace(['App\Clients\\', '\\'], ['', '_'], $calledClass);
        return substr($module, 0, strrpos($module, '_'));
    }

    /**
     * 根据调用类提前service名称
     *
     * @return false|string
     * @author pengjch 2024314 12:0:34
     */
    protected function extractServiceName()
    {
        $calledClass = get_called_class();
        return substr($calledClass, strrpos($calledClass, '\\') + 1);
    }

    /**
     * __call
     *
     * @param $method
     * @param $args
     * @return false|mixed
     * @throws \Exception
     * @author 2021-03-14 11:25:18
     */
    public function __call($method, $args)
    {
        switch (env('SERVICE_CALL_STRATEGY', 'remote')) {
            case 'remote':
                return $this->callRemoteService($method, $args);
            case 'local':
                return $this->callLocalService($method, $args);
            default:
                throw new \Exception('error strategy');
        }
    }
}