go + net/rpc + protobuf

0.protoc文件编写编译

a. protoc协议中消息字段定义(统一使用驼峰格式命名,单词之间不要使用下换线连接),使得生成的消息协议,在rpc api编解码和 json编解码中,json字段名是一样,这样调用方,使用发送kafka消息,或者调用go-micro API中生成json数据时候,只要写一套json就可以了

b.枚举中的值不用加前缀,编译的时候自动会加,如OWNER在pb.go中会定义成: MemberType_OWNER(区分大小写的)

c. import其他proto的时候,2个文件呢中的pakcet 名字要一样,如package protocol;

  

enum MemberType {
    BEGIN = 0; 
    OWNER = 1;  //群主
    ADMIN = 2;  //管理员
    NORMAL = 3; //普通成员
}

编译(可以直接下载protoc文件的二进制文件):

protoc  --go_out=. msg.proto

 

根据.proto文件生成.pb.go,在gopath的src目录下,protoc --proto_path=./  --go_out=./   goim/libs/model/msg.proto

 

 

1.net/rpc 服务端

线程模型 
每个新链接使用一个协程处理 , 看源码net/rpc/server.go 

// Accept accepts connections on the listener and serves requests
// for each incoming connection. Accept blocks until the listener
// returns a non-nil error. The caller typically invokes Accept in a
// go statement.
func (server *Server) Accept(lis net.Listener) {
	for {
		conn, err := lis.Accept()
		if err != nil {
			log.Print("rpc.Serve: accept:", err.Error())
			return
		}
		go server.ServeConn(conn)
	}
}

同一个链接的每个函数调用,启动一个协程处理

// ServeCodec is like ServeConn but uses the specified codec to
// decode requests and encode responses.
func (server *Server) ServeCodec(codec ServerCodec) {
	sending := new(sync.Mutex)
	wg := new(sync.WaitGroup)
	for {
		service, mtype, req, argv, replyv, keepReading, err := server.readRequest(codec)
		if err != nil {
			if debugLog && err != io.EOF {
				log.Println("rpc:", err)
			}
			if !keepReading {
				break
			}
			// send a response if we actually managed to read a header.
			if req != nil {
				server.sendResponse(sending, req, invalidRequest, codec, err.Error())
				server.freeRequest(req)
			}
			continue
		}
		wg.Add(1)
		go service.call(server, sending, wg, mtype, req, argv, replyv, codec)
	}
	// We've seen that there are no more requests.
	// Wait for responses to be sent before closing codec.
	wg.Wait()
	codec.Close()
}

2. 客户端模型

连接成功后创建了一个 go input(),作为接收 "回调" 协程,接收到数据后,根据发送的seq id,找到对应的调用Call,然后调用Call.done(), 阻塞的rpc调用,就可以返回了,否则rpc调用一直阻塞着

不具备断链重连功能,没有底层实现心跳

 

3.rpc/net提供一个默认的 var DefaultServer = NewServer(), 可以Register多个对象

rpc.Register(&logicRpc)

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值