把Laravel的控制器变为RPC服务进行调用


timg (1).jpg

最近准备改造一个php的api service准备用作RPC远程调用,不想改变原有的代码(懒😂)。选择的rpc框架是hprose,直接使用控制器的成员方法肯定是不行的,那让我们来改造一下吧。

主要因为request实例无法由hprose从客户端传给服务端,在hprose的中间件中模拟一个就行了。

服务端

use Hprose\Http\Server;

class ServiceInit
{
    public function init()
    {
        $server = new Server();
        //定义需要远程调用的控制器并设置其别名
        $classes = [
            [new HomeController(),'home']
        ];

        //中间件
        $requestHandler = function ($name, array &$args, stdClass $context, Closure $next) {
            //模拟request
            $request = new Request();
            $request->server->add($args[0]);
            $request->headers->add($args[1]);
            $request->replace($args[2]);
            //重置参数
            $params = [$request];
            for ($i = 3; $i < count($args); $i++) {
                $params[] = $args[$i];
            }
            $result = $next($name, $params, $context);
            return $result;
        };
        foreach ($classes as $item) {
            if (is_array($item)) {
                $class = $item[0];
                $alias = $item[1];
            } else {
                $class = $item;
                $aliasExplode = explode('\\', get_class($item));
                $alias = $aliasExplode[count($aliasExplode) - 1];
            }

            $server->addInstanceMethods($class, '', $alias);

        }
        $server->addInvokeHandler($requestHandler);
        $server->start();
    }

}

客户端

为了调用方便,稍稍封装一下:注意参数的传递

use Hprose\Http\Client;

/**
 * Class RpcClient
 * @package App\Service
 *
 * @method home_index($array, $string)
 */
class RpcClient
{
    protected $client;

    public function __construct()
    {
        try {
            $urlList = explode(',',env('RPC_SERVERS'));
            $client = Client::create($urlList, false);
            $this->client = $client;
        } catch (\Exception $e) {
            throw new \Exception('rpc client create error', 500);
        }
    }

    public function __call($name, $arguments)
    {
        $request = app('request');
        $params = array_merge([$request->server(), $request->header()], $arguments);
        return call_user_func_array([$this->client, $name], $params);
    }


本文 暂无 评论

Top