记录下最后的倔强吧

121 阅读1分钟

本文不涉及技术分享,想看技术博文的可以右上角关掉了。

1. 唠叨

自从大一勤工助学去了信息中心,阴差阳错接触了PHP,至今马上10年了,互联网发展,从最早的单机应用,到Nginx负载均衡,再到如今k8s+微服务逐渐普及,最好的语言不可避免的要走下坡路了,毕竟毕竟,还是脚本语言啊。面对微服务架构,PHP像是网文里废灵根的少年,强行修真一样,唉

记录下一个超级粗糙的PHP的远程调用,再见了,今后拥抱DevOps+持续交付+微服务+容器吧。

2.RpcServer.php

<?php
class RpcServer{

    private $port = 0;
    private $host = '';

    public function __construct($host, $port){
        $this->host = $host;
        $this->port = $port;
    }

    public function run(){
    	$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
    	if (!$socket) {
    		echo "socket_create falied \n";
    		return;
    	}
		//为套接字绑定ip和端口
		if( !socket_bind($socket, $this->host, $this->port) ) return;
		//监听socket
		if( !socket_listen($socket,4) ) return;

		while(true)
		{
		    //接收客户端请求
		    if(($msgsocket = socket_accept($socket)) !== false)
		    {
		        //读取请求内容
		        $buf = socket_read($msgsocket, 1024);
		        echo "Received msg: $buf \n";
		        $obj = json_decode($buf, true);
		        if (is_array($obj)
		        	&& isset($obj['Class'])
		        	&& isset($obj['Method'])
		    	) {
		    		$instance = (new $obj['Class']);
		    		$method   = $obj['Method'];
		        	$str = $instance->$method(...$obj['params']);
		        }else{
		        	$str = "RPC: Hello!";
		        }		        
		        //向连接的客户端发送数据 
		        socket_write($msgsocket, $str,strlen($str));
		        //操作完之后需要关闭该连接否则 feof() 函数无法正确识别打开的句柄是否读取完成
		        socket_close($msgsocket);
		    }
		}
	}
}
//RPC测试类
class Test{
    public function add($a, $b){
        return $a + $b;
    }
}

( new RpcServer('192.168.27.128', 8888) )->run();

3.RpcClient.php

<?php
class RpcClient{
    private $className = '';

    private function __construct($className){
        $this->className = $className;
    }

    public static function getInstance($className){
        return new RpcClient($className);
    }

    public function __call($name, $arguments){
    	var_dump($arguments);
        $st = json_encode([
            'Class' => $this->className,
            'Method' => $name,
            'params' => $arguments,
        ]);
		$length = strlen($st);
		//创建tcp套接字
		$socket = socket_create(AF_INET,SOCK_STREAM,SOL_TCP);
		if (!$socket) {
			echo 'socket_create failed'.PHP_EOL;
			return;
		}
		//连接tcp
		if(!socket_connect($socket, '192.168.27.128',8888)){
			echo 'socket_connect failed'.PHP_EOL;
			return;
		}
		//向打开的套集字写入数据(发送数据)
		$s = socket_write($socket, $st, $length);
		//从套接字中获取服务器发送来的数据
		$msg = socket_read($socket,1024);

		echo 'Server :'.$msg.PHP_EOL;
		//关闭连接
		socket_close($socket);
    }
}

$test = RpcClient::getInstance('Test');
echo $test->add(4, 6);

4.Result

在局域网内另一台调用:

[root@localhost ~]# php RPCClient.php 
array(2) {
  [0]=>
  int(4)
  [1]=>
  int(6)
}
Server :10