package main import ( "errors" "fmt" "net" "net/http" "net/rpc" ) type Calculator struct{} type Nums struct { Num1 float64 Num2 float64 } type Result struct { Num float64 } // Add 加法运算 func (calc *Calculator) Add(nums Nums, result *Result) (err error) { fmt.Println("有客户端调用Calculator.Add()") result.Num = nums.Num1 + nums.Num2 return } // Subtract 减法运算 func (calc *Calculator) Subtract(nums Nums, result *Result) (err error) { fmt.Println("有客户端调用Calculator.Subtract()") result.Num = nums.Num1 - nums.Num2 return } // Multiply 乘法运算 func (calc *Calculator) Multiply(nums Nums, result *Result) (err error) { fmt.Println("有客户端调用Calculator.Multiply()") result.Num = nums.Num1 * nums.Num2 return } // Divide 除法运算 func (calc *Calculator) Divide(nums Nums, result *Result) (err error) { fmt.Println("有客户端调用Calculator.Divide()") // 重要提醒:这里不能用defer...recover的方式捕获panic,因为recover()恒为nil if nums.Num2 == 0 { return errors.New("除数不能为零") } result.Num = nums.Num1 / nums.Num2 return } func main() { var err error var listener net.Listener err = rpc.Register(new(Calculator)) if err != nil { panic("注册RPC服务失败:" + err.Error()) } rpc.HandleHTTP() listener, err = net.Listen("tcp", ":10086") // RPC服务端口号 if err != nil { panic("监听RPC服务失败:" + err.Error()) } defer func(listener net.Listener) { _ = listener.Close() }(listener) err = http.Serve(listener, nil) if err != nil { panic("启动RPC服务失败:" + err.Error()) } }
package main import ( "fmt" "net/rpc" ) type Nums struct { Num1 float64 Num2 float64 } type Result struct { Num float64 } func main() { var err error var client *rpc.Client var nums Nums var result Result client, err = rpc.DialHTTP("tcp", ":10086") if err != nil { panic("连接RPC服务器失败:" + err.Error()) } // ========== 加法运算 ========== // nums.Num1 = 5 nums.Num2 = 2 result = Result{} err = client.Call("Calculator.Add", nums, &result) if err != nil { fmt.Println("调用Calculator.Add()失败:" + err.Error()) } else { fmt.Printf("调用Calculator.Add()成功:%v + %v = %v \n", nums.Num1, nums.Num2, result.Num) // 调用Calculator.Add()成功:5 + 2 = 7 } // ========== 减法运算 ========== // nums.Num1 = 5 nums.Num2 = 2 result = Result{} err = client.Call("Calculator.Subtract", nums, &result) if err != nil { fmt.Println("调用Calculator.Subtract()失败:" + err.Error()) } else { fmt.Printf("调用Calculator.Subtract()成功:%v - %v = %v \n", nums.Num1, nums.Num2, result.Num) // 调用Calculator.Subtract()成功:5 - 2 = 3 } // ========== 乘法运算 ========== // nums.Num1 = 5 nums.Num2 = 2 result = Result{} err = client.Call("Calculator.Multiply", nums, &result) if err != nil { fmt.Println("调用Calculator.Multiply()失败:" + err.Error()) } else { fmt.Printf("调用Calculator.Multiply()成功:%v * %v = %v \n", nums.Num1, nums.Num2, result.Num) // 调用Calculator.Multiply()成功:5 * 2 = 10 } // ========== 除法运算(除数不为零) ========== // nums.Num1 = 5 nums.Num2 = 2 result = Result{} err = client.Call("Calculator.Divide", nums, &result) if err != nil { fmt.Println("调用Calculator.Divide()失败:" + err.Error()) } else { fmt.Printf("调用Calculator.Divide()成功:%v / %v = %v \n", nums.Num1, nums.Num2, result.Num) // 调用Calculator.Divide()成功:5 / 2 = 2.5 } // ========== 除法运算(除数为零) ========== // nums.Num1 = 5 nums.Num2 = 0 result = Result{} err = client.Call("Calculator.Divide", nums, &result) if err != nil { fmt.Println("调用Calculator.Divide()失败:" + err.Error()) // 调用Calculator.Divide()失败:除数不能为零 } else { fmt.Printf("调用Calculator.Divide()成功:%v / %v = %v \n", nums.Num1, nums.Num2, result.Num) } // ========== 取模运算(服务端不存在该方法) ========== // nums.Num1 = 5 nums.Num2 = 2 result = Result{} err = client.Call("Calculator.Mod", nums, &result) if err != nil { fmt.Println("调用Calculator.Mod()失败:" + err.Error()) // 调用Calculator.Mod()失败:rpc: can't find method Calculator.Mod } else { fmt.Printf("调用Calculator.Mod()成功:%v %% %v = %v \n", nums.Num1, nums.Num2, result.Num) } } // ========== 输出结果·开始 ========== // // 调用Calculator.Add()成功:5 + 2 = 7 // 调用Calculator.Subtract()成功:5 - 2 = 3 // 调用Calculator.Multiply()成功:5 * 2 = 10 // 调用Calculator.Divide()成功:5 / 2 = 2.5 // 调用Calculator.Divide()失败:除数不能为零 // 调用Calculator.Mod()失败:rpc: can't find method Calculator.Mod // ========== 输出结果·结束 ========== //
package main import ( "errors" "fmt" "net" "net/rpc" "net/rpc/jsonrpc" ) type Calculator struct{} type Nums struct { Num1 float64 Num2 float64 } type Result struct { Num float64 } // Add 加法运算 func (calc *Calculator) Add(nums Nums, result *Result) (err error) { fmt.Println("有客户端调用Calculator.Add()") result.Num = nums.Num1 + nums.Num2 return } // Subtract 减法运算 func (calc *Calculator) Subtract(nums Nums, result *Result) (err error) { fmt.Println("有客户端调用Calculator.Subtract()") result.Num = nums.Num1 - nums.Num2 return } // Multiply 乘法运算 func (calc *Calculator) Multiply(nums Nums, result *Result) (err error) { fmt.Println("有客户端调用Calculator.Multiply()") result.Num = nums.Num1 * nums.Num2 return } // Divide 除法运算 func (calc *Calculator) Divide(nums Nums, result *Result) (err error) { fmt.Println("有客户端调用Calculator.Divide()") // 重要提醒:这里不能用defer...recover的方式捕获panic,因为recover()恒为nil if nums.Num2 == 0 { return errors.New("除数不能为零") } result.Num = nums.Num1 / nums.Num2 return } func main() { var err error var listener net.Listener err = rpc.Register(new(Calculator)) if err != nil { panic("注册RPC服务失败:" + err.Error()) } listener, err = net.Listen("tcp", ":10086") // RPC服务端口号 if err != nil { panic("监听RPC服务失败:" + err.Error()) } defer func(listener net.Listener) { _ = listener.Close() }(listener) for { var conn net.Conn conn, err = listener.Accept() if err != nil { panic("连接RPC服务失败:" + err.Error()) } go func(conn net.Conn) { defer func(conn net.Conn) { _ = conn.Close() }(conn) jsonrpc.ServeConn(conn) }(conn) } }
<?php /** * JSONRPC客户端 */ class JSONRPCClient { private $conn; /** * 构造方法 * * @param string $url RPC服务器主机地址 */ public function __construct($url) { $parse = (array)parse_url($url); $hostname = "{$parse['scheme']}://{$parse['host']}"; $port = $parse['port']; $this->conn = fsockopen($hostname, $port); } /** * 调用RPC服务器的方法 * * @param string $method 方法名 * @param array $params 方法参数 * @return array 方法返回值 */ public function call($method, $params) { $reply = []; if ($this->conn) { $data = ['method' => $method, 'params' => [$params], 'id' => time()]; // 说明:id参数可不传递 $data = json_encode($data); $fwrite = fwrite($this->conn, $data); if ($fwrite !== false) { $fgets = fgets($this->conn); $reply = json_decode($fgets, true); } } return $reply; } /** * 断开与RPC服务器的连接 * * @return void */ public function disconnect() { if ($this->conn) { fclose($this->conn); } } } $client = new JSONRPCClient('tcp://***.***.***.***:10086'); //========== 加法运算 ==========// $nums = ['Num1' => 5, 'Num2' => 2]; $reply = $client->call('Calculator.Add', $nums); if ($reply['error'] !== NULL) { echo "调用Calculator.Add()失败:{$reply['error']}" . PHP_EOL; } else { echo "调用Calculator.Add()成功:{$nums['Num1']} + {$nums['Num2']} = {$reply['result']['Num']}" . PHP_EOL; // 调用Calculator.Add()成功:5 + 2 = 7 } //========== 减法运算 ==========// $nums = ['Num1' => 5, 'Num2' => 2]; $reply = $client->call('Calculator.Subtract', $nums); if ($reply['error'] !== NULL) { echo "调用Calculator.Subtract()失败:{$reply['error']}" . PHP_EOL; } else { echo "调用Calculator.Subtract()成功:{$nums['Num1']} - {$nums['Num2']} = {$reply['result']['Num']}" . PHP_EOL; // 调用Calculator.Subtract()成功:5 - 2 = 3 } //========== 乘法运算 ==========// $nums = ['Num1' => 5, 'Num2' => 2]; $reply = $client->call('Calculator.Multiply', $nums); if ($reply['error'] !== NULL) { echo "调用Calculator.Multiply()失败:{$reply['error']}" . PHP_EOL; } else { echo "调用Calculator.Multiply()成功:{$nums['Num1']} * {$nums['Num2']} = {$reply['result']['Num']}" . PHP_EOL; // 调用Calculator.Multiply()成功:5 * 2 = 10 } //========== 除法运算(除数不为零) ==========// $nums = ['Num1' => 5, 'Num2' => 2]; $reply = $client->call('Calculator.Divide', $nums); if ($reply['error'] !== NULL) { echo "调用Calculator.Divide()失败:{$reply['error']}" . PHP_EOL; } else { echo "调用Calculator.Divide()成功:{$nums['Num1']} / {$nums['Num2']} = {$reply['result']['Num']}" . PHP_EOL; // 调用Calculator.Divide()成功:5 / 2 = 2.5 } //========== 除法运算(除数为零) ==========// $nums = ['Num1' => 5, 'Num2' => 0]; $reply = $client->call('Calculator.Divide', $nums); if ($reply['error'] !== NULL) { echo "调用Calculator.Divide()失败:{$reply['error']}" . PHP_EOL; // 调用Calculator.Divide()失败:除数不能为零 } else { echo "调用Calculator.Divide()成功:{$nums['Num1']} / {$nums['Num2']} = {$reply['result']['Num']}" . PHP_EOL; } //========== 取模运算(服务端不存在该方法) ==========// $nums = ['Num1' => 5, 'Num2' => 2]; $reply = $client->call('Calculator.Mod', $nums); if ($reply['error'] !== NULL) { echo "调用Calculator.Mod()失败:{$reply['error']}" . PHP_EOL; // 调用Calculator.Mod()失败:rpc: can't find method Calculator.Mod } else { echo "调用Calculator.Mod()成功:{$nums['Num1']} % {$nums['Num2']} = {$reply['result']['Num']}" . PHP_EOL; } $client->disconnect(); //========== 输出结果·开始 ==========// // 调用Calculator.Add()成功:5 + 2 = 7 // 调用Calculator.Subtract()成功:5 - 2 = 3 // 调用Calculator.Multiply()成功:5 * 2 = 10 // 调用Calculator.Divide()成功:5 / 2 = 2.5 // 调用Calculator.Divide()失败:除数不能为零 // 调用Calculator.Mod()失败:rpc: can't find method Calculator.Mod //========== 输出结果·结束 ==========//
Copyright © 2024 码农人生. All Rights Reserved