golang的jsonRPC调用

package rpcz

// first we create a simple golang rpc server based on socket
import (
    "fmt"
    "net"
    "net/rpc"
    "net/rpc/jsonrpc"
)

type Counter struct {
    Sum int
}

func (this *Counter) Add(i int, r *int) error {
    this.Sum += i
    *r = this.Sum
    fmt.Printf("i: %v", i)
    return nil
}

func NewJsonRpcSocketServer() {

    rpc.Register(new(Counter))

    l, err := net.Listen("tcp", ":3333")
    if err != nil {
        fmt.Printf("Listener tcp err: %s", err)
        return
    }

    for {
        fmt.Println("wating...")
        conn, err := l.Accept()
        if err != nil {
            fmt.Sprintf("accept connection err: %s\n", conn)
        }
        go jsonrpc.ServeConn(conn)
    }

}

func NewJsonRpcSocketClient() {
    conn, err := net.DialTimeout("tcp", "127.0.0.1:3333", 1000*1000*1000*30)
    if err != nil {
        fmt.Printf("create client err:%s\n", err)
        return
    }
    defer conn.Close()

    client := jsonrpc.NewClient(conn)
    var reply int
    err = client.Call("Counter.Add", 10, &reply)

    fmt.Printf("reply: %s, err: %s\n", reply, err)

}

 

上面的NewJsonRpcSocketServer()方法创建了一个基于tcp协议的json-rpc服务器,NewJsonRpcSocketClient()方法示范了golang端的简单调用(注意是基于tcp,而不是http协议!稍后会给出调用"github.com/gorilla/rpc/json"实现的基于http协议的调用方法)。但这不是重点,下面看一下Java客户端的调用,可以看出来,这也是一个基于socket的通信:

 

package cn;

import com.googlecode.jsonrpc4j.JsonRpcClient;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.*;

/**
 * Created by geomantic on 15/8/21.
 */
public class SocketClient {

    public static void main(String[] args) {
        try {
            Socket socket = new Socket("127.0.0.1", 3333);
            JsonRpcClient client = new JsonRpcClient();

            InputStream ips = socket.getInputStream();
            OutputStream ops = socket.getOutputStream();

            int reply = client.invokeAndReadResponse("Counter.Add", new Object[]{1001}, int.class, ops, ips);

            System.out.println("reply: " + reply);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }

    }
}

 

上面的java代码初步示范了如何异步调用golang服务端的两个很重要的约束:

  1.  golang服务端的方法名注册和调用保持一致,格式为: 结构体名.方法名, 如上面的Counter.Add。

  2. 能够注册的方法必须满足指定的函数签名:

       func (t *T) MethodName(argType T1, replyType *T2) error 。

   入参有且只有两个,第一个是被调用函数的输入参数,第二个是被调用函数的输出参数。 返回值只有一个error类型。这三个参数一个都不能变。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值