Protobuf-RPC in Go

878 views
Skip to first unread message

chai2010

unread,
Apr 25, 2013, 10:55:26 PM4/25/13
to golang-nuts, golang中文小组
Hi, I have write a Protobuf-RPC in Go.

1. Download (can't use `go get`)


2. Insall `net/rpc/protoprc` and `protoc-gen-go`

- Add gopath dir to $GOPATH
- Add gopath/bin dir to $PATH

go install encoding/protobuf/protoc-gen-go
go test net/rpc/protorpc/service.pb
go test net/rpc/protorpc

Note:
- You need install protoc app on !Windows OS
to gen rpc stub file for `protoc-gen-go`

3. How to use (from `net/rpc/protorpc/doc.go`)?

Here is a simple proto file("arith.pb/arith.proto"):

package arith;

// At least one of xx_generic_services is true
option cc_generic_services = true;
option java_generic_services = true;
option py_generic_services = true;

message ArithRequest {
optional int32 a = 1;
optional int32 b = 2;
}

message ArithResponse {
optional int32 val = 1;
optional int32 quo = 2;
optional int32 rem = 3;
}

service ArithService {
rpc multiply (ArithRequest) returns (ArithResponse);
rpc divide (ArithRequest) returns (ArithResponse);
}

Then use "protoc-gen-go" to generate "arith.pb.go" file(include rpc stub):

$ go install encoding/protobuf/protoc-gen-go
$ cd arith.pb && protoc --go_out=. arith.proto

The server calls (for TCP service):

package server

import (
"encoding/protobuf/proto"
"errors"

"./arith.pb"
)

type Arith int

func (t *Arith) Multiply(args *arith.ArithRequest, reply *arith.ArithResponse) error {
reply.Val = proto.Int32(args.GetA() * args.GetB())
return nil
}

func (t *Arith) Divide(args *arith.ArithRequest, reply *arith.ArithResponse) error {
if args.GetB() == 0 {
return errors.New("divide by zero")
}
reply.Quo = proto.Int32(args.GetA() / args.GetB())
reply.Rem = proto.Int32(args.GetA() % args.GetB())
return nil
}

func main() {
go arith.ListenAndServeArithService("tcp", ":1984", new(Arith))
}

At this point, clients can see a service "Arith" with methods "Arith.Multiply" and
"Arith.Divide". To invoke one, a client first dials the server:

client, stub, err := arith.DialArithService("tcp", "127.0.0.1:1984")
if err != nil {
log.Fatal(`arith.DialArithService("tcp", "127.0.0.1:1984"):`, err)
}
defer client.Close()

Then it can make a remote call with stub:

var args ArithRequest
var reply ArithResponse

args.A = proto.Int32(7)
args.B = proto.Int32(8)
if err = stub.Multiply(&args, &reply); err != nil {
log.Fatal("arith error:", err)
}
fmt.Printf("Arith: %d*%d=%d", args.GetA(), args.GetB(), reply.GetVal())

Is very simple to use "Protobuf-RPC" with "protoc-gen-go" tool. Try it out.

--
chaishushan
http://my.oschina.net/chai2010

chai2010

unread,
May 3, 2013, 11:02:27 PM5/3/13
to golang-nuts, golang中文小组
protorpc的代码更新到以下的网址:


目前还在完善C++部分的RPC实现(C++部分代码没有上传).
完成后会统一更新上去.

2013/4/26 chai2010 <chais...@gmail.com>

chai2010

unread,
May 8, 2013, 8:46:15 AM5/8/13
to golang-nuts, golang中文小组
已经实现了一个简单的C++版本, 代码已经更新.

Go和C++实现的服务端和客户端的例子:

Kenneth Tse

unread,
Dec 11, 2014, 1:53:36 AM12/11/14
to golan...@googlegroups.com, golang...@googlegroups.com
Hi chai2010:

    I have tried you protobuf rpc, it works fine for golang server and golang client.
    
    But I found I cann't call python rpc server, or use python client to request golang server. Is this a bug or you haven't consider cross-language compatibility?

    btw, I use https://code.google.com/p/protobuf-socket-rpc/ to make python protobuf rpc work.

chai2010

unread,
Dec 11, 2014, 2:07:07 AM12/11/14
to Kenneth Tse, golang-nuts, golang中文小组

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--

钟佳欣

unread,
Dec 11, 2014, 3:30:22 AM12/11/14
to golan...@googlegroups.com, golang...@googlegroups.com
能不能把整个工程移植到github里面呢?你看看golang已经移植了。方便国内的翻墙困难的人。

在 2013年4月26日星期五UTC+8上午10时55分26秒,chai2010写道:
Reply all
Reply to author
Forward
0 new messages