記錄下最後的倔強吧

tfzh發表於2022-03-19

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

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

相關文章