|
Go语言作为RPC的callee端,提供两个文件,一个是执行服务的程序:Myservcie.go:
package main
type Args struct {
X int
Y int
}
type ServiceCompute struct{}
func (s *ServiceCompute) Add(args *Args, reply *int) error {
*reply = args.X + args.Y
return nil
}
一个是处理 TCP链接请求的程序server.go:
package main
import (
"fmt"
"log"
"net"
"net/rpc"
"net/rpc/jsonrpc"
)
func main() {
fmt.Println("Go语言的研究-----------json 协议的RPC")
fmt.Println("--------------------------------------------------")
test()
}
func test() {
service := new(ServiceCompute)
rpc.Register(service)
myListener, err := net.Listen("tcp", "0.0.0.0:30002")
if err != nil {
log.Fatal("监听出现问题:", err)
}
defer myListener.Close()
for {
conn, err := myListener.Accept()
if err != nil {
log.Fatal("建立连接出现问题:", err)
return
}
log.Println("连接的客户端是:", conn.RemoteAddr())
rpc.ServeCodec(jsonrpc.NewServerCodec(conn)) // jsonrpc.NewServerCodec 会自动开启单独的goroutine进行处理
}
}
使用Go写一个客户端做并发测试程序:client.go:
package main
import (
"fmt"
"log"
"net"
"net/rpc"
"net/rpc/jsonrpc"
"sync"
)
type Args struct {
X int
Y int
}
func main() {
fmt.Println("Json rpc client的处理")
fmt.Println("--------------------------------------")
test()
}
var wg sync.WaitGroup
func test() {
wg.Add(100)
for i := 0; i < 100; i++ {
clientcall()
}
wg.Wait()
}
func clientcall() {
defer wg.Done()
//建立rpc 的连接
conn, err := net.Dial(&#34;tcp&#34;, &#34;127.0.0.1:30002&#34;)
if err != nil {
log.Fatal(&#34;连接RPC服务器出错:&#34;, err)
}
client := rpc.NewClientWithCodec(jsonrpc.NewClientCodec(conn))
defer client.Close()
//同步调用
/*
args := &Args{50, 100}
var reply int
err = client.Call(&#34;ServiceCompute.Add&#34;, args, &reply)
if err != nil {
log.Fatal(&#34;远程调用出错&#34;, err)
return
}
fmt.Printf(&#34;ServiceCompute.Add 结果:%v+%v=%v\n&#34;, args.X, args.Y, reply)
*/
//异步调用
var reply int
args := &Args{50, 100}
asyncCall := client.Go(&#34;ServiceCompute.Add&#34;, args, &reply, nil)
replyCall := <-asyncCall.Done
if replyCall.Error != nil {
log.Fatal(&#34;远程调用出错&#34;, replyCall.Error)
return
}
fmt.Printf(&#34;ServiceCompute.Add 结果:%v+%v=%v\n&#34;, args.X, args.Y, reply)
}
PHP 端的就送 rpc 调用:rpc_client.php
<?php
class JsonRPC {
private $conn;
function __construct($host, $port) {
$this->conn = fsockopen($host, $port, $errno, $errstr, 3);
if (!$this->conn) {
return false;
}
}
public function Call($method, $params) {
if (!$this->conn) {
return false;
}
$err = fwrite($this->conn, json_encode(array(
&#39;method&#39; => $method,
&#39;params&#39; => array($params),
&#39;id&#39; => 0,
)) . &#34;\n&#34;);
if ($err === false){
return false;
}
stream_set_timeout($this->conn, 0, 3000);
$line = fgets($this->conn);
if ($line === false) {
return NULL;
}
return json_decode($line, true);
}
}
$client = new JsonRPC(&#34;127.0.0.1&#34;, 30002);
$r = $client->Call(&#34;ServiceCompute.Add&#34;, array(&#39;X&#39; => 30, &#39;Y&#39; => 40));
var_dump($r); |
|