分享
  1. 首页
  2. 文章

golang与java间的json-rpc跨语言调用

geomantic · · 10060 次点击 · · 开始浏览
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

关于如何使用golang调用rpc和json-rpc,网上虽然有很多的帖子,但都仅仅是golang程序间通信,没有牵涉到跨语言调用的问题。在使用golang开发服务端程序的时候,不可避免的要与其他语言的程序进行交互,特别是json-rpc这的协议,本身就应该是用在不同的平台间的调用上的(因为golang程序间的交流已经有了封闭的用gob编码解码的rpc包了,我们自然而言的会想到用json-rpc来提供对其他语言的支持)。本文就来详细探究一下如何实现golang与java之间的json-rpc调用。

  • 首先,实现一个基于socket的java调用golang的样例(这个方法不需要第三方golang库,但是仅能通过tcp协议通信。如果要通过http协议通信的话,必须自己写一个或者用第三方的库,后面会有介绍)
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类型。这三个参数一个都不能变。

但是基于tcp的调用,对于用惯了http协议的人会感觉写起来很蛋疼,可能更多的人还是习惯用http来解析。但是由于解决的方法有比较琐碎的细节处理,而且牵涉到一些第三方库的代码修改,考虑到篇幅问题准备另起一篇,在下一篇中示范一下用http协议通信实现的rpc实现。


有疑问加站长微信联系(非本文作者)

本文来自:博客园

感谢作者:geomantic

查看原文:golang与java间的json-rpc跨语言调用

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

关注微信
10060 次点击
暂无回复
添加一条新回复 (您需要 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传

用户登录

没有账号?注册
(追記) (追記ここまで)

今日阅读排行

    加载中
(追記) (追記ここまで)

一周阅读排行

    加载中

关注我

  • 扫码关注领全套学习资料 关注微信公众号
  • 加入 QQ 群:
    • 192706294(已满)
    • 731990104(已满)
    • 798786647(已满)
    • 729884609(已满)
    • 977810755(已满)
    • 815126783(已满)
    • 812540095(已满)
    • 1006366459(已满)
    • 692541889

  • 关注微信公众号
  • 加入微信群:liuxiaoyan-s,备注入群
  • 也欢迎加入知识星球 Go粉丝们(免费)

给该专栏投稿 写篇新文章

每篇文章有总共有 5 次投稿机会

收入到我管理的专栏 新建专栏