Go net/rpc 包总结
来源:互联网 发布:网络打鱼秘籍 编辑:程序博客网 时间:2024/05/23 19:17
RPC
rpc远程过程调用,go net/rpc包提供了通过网络访问一个对象的方法的能力。服务器需要注册对象, 通过对象的类型名暴露这个服务。注册后这个对象的输出方法就可以远程调用,这个库封装了底层传输的细节,包括序列化。服务器可以注册多个不同类型的对象,但是注册相同类型的多个对象的时候回出错。
通过阅读net/rpc包你可以学到互斥锁、goroutine、map、channel、interface、反射等相关知识。
Clinet.go
阅读源码我们可以得知连接分为
DialHTTP —— 连接到指定的网络地址http RPC服务器,监听默认的HTTP RPC路径
DialHTTPPath —— 连接在指定的网络地址和路径HTTP RPC服务器
NewClient —— 返回一个新的客户端句柄,在链接的有效期内链接服务端发送请求
NewClientWithCodec——与NewClient相似,但是它使用指定得编码器编码请求,解码返回
我们可以看出DialHTTP与DialHTTPPath可以归为一组,NewClient与NewClientWithCodec可以归为一组。
DialHTTP 和 DialHTTPPath 是通过HTTP的方式和服务器建立连接,他俩的区别之在于是否设置上下文路径。
NewClient使用默认编码NewClientWithCodec使用其它编码。
Clinet端比较重要的input方法。
从代码中我们可以看出其在一个for循环中首先读取了头,然后从map中获取值若为nil则调用了ReadResponseBody方法并传入了nil迫使放弃读取。这也印证了代码中所说的ReadResponseHeader与ReadResponseBody为成对调用的。
另一个为异步调用的Go异步调用函数。它返回call结构体。done的通道将在调用完成时发出相同的调用对象来发出信号。如果done为nil,Go将会分配一个新的channel。如果non-nil,done必须有缓存否则会崩溃。
故Client端在使用时有如下注意事项:
1. channel必须为有缓存的
2. ReadResponseHeader与ReadResponseBody配合使用
3. 客户端在一个链接结束后调用Close关闭
4. 若ReadResponseHeader失败则需要调用ReadResponseBody并传入nil迫使放弃。
Server.go
在服务端注册并发布方法需要满足一下条件:
- 导出的方法和导出的类型
- 两个参数都是导出的类型
- 第二个参数必须为指针
- 返回值为一个错误类型
注册方法:
Register与RegisterName,RegisterName与Register类似,但是使用传入的名字作为类型,代替接收者的具体类型。
监听
Accept—Accept接收监听的连接。并为每一个进入的连接提供请求
HandleHTTP—HandleHTTP再RPCPath注册一个HTTP handler作为RPC的消息。它必须调用http.Serve(),再go语句中调用
ServeCodec—运行这个server在一个单独连接
ServeConn—为连接提供服务直到客户端挂起,调用者使用go ServeConn调用。 ServeConn在连接中使用gob包进行写格式化
ServeHTTP—ServeHTTP执行http.Handler应答RPC请求
ServeRequest—就像是ServeCodec但是同步服务的请求。它在完成后不关闭编解码器
简单的示例
clinet.go
package mainimport ( "net/rpc" "fmt")const ( PORT = "127.0.0.1:10012" PROXY = "tcp")type Hello struct { StrHello string}type ResStr struct { StrHi string}func main() { client, err := rpc.DialHTTP(PROXY, PORT) if err != nil { fmt.Println("dialing:", err) } var args = Hello{" Test rpc",} var reply string err = client.Call("Say.SayHello", args, &reply) if err != nil { fmt.Println("arith error:", err) } fmt.Println(reply) args = Hello{" Go invokes the function asynchronously",} res := new(ResStr) resCall := client.Go("Say.SayHi",args,&res,nil) //异步调用 replyCall := <-resCall.Done if replyCall.Error != nil { fmt.Println("arith error:", replyCall.Error) } fmt.Println(res.StrHi)}
server.go
package mainimport ( "net/rpc" "net" "fmt" "net/http")const ( SAY = "Hello" PORT = ":10012" PROXY = "tcp")type Hello struct { StrHello string}type ResStr struct { StrHi string}type Say intfunc (this *Say) SayHello(args *Hello, reply *string) error { *reply = SAY + args.StrHello return nil}func (this *Say) SayHi(args *Hello, reply *ResStr) error { reply.StrHi = SAY + args.StrHello return nil}func main() { hi := new(Say) rpc.Register(hi) rpc.HandleHTTP() l, e := net.Listen(PROXY,PORT) if e != nil { fmt.Println("listen error:", e) } http.Serve(l, nil)}
- Go net/rpc 包总结
- Go net/http包
- Go net包介绍
- Go RPC
- Go RPC
- go net 包详解1
- Go语言学习之net包(The way to go)
- go语言RPC
- go RPC服务过程
- go rpc 简单用法
- 【Go】包
- rpc的go 和 call
- go利用x/net/html包实现的蜘蛛
- go语言net/http包解析http body之坑
- Go利用net/http包搭建Web服务器
- Go源码分析 net/http包分析:追溯到socket
- 七、GO语言库学习--net/url包--go语言笔记
- Go语言学习之net/http包(The way to go)
- POJ 2546 Circular Area 笔记
- MAC 上windows的caps lock 按下变成大写不能切换问题
- swift3.0 as、as!、as? 关键字 三种操作符的使用
- 从源码角度理解Android线程
- 2-SAT
- Go net/rpc 包总结
- SpringMVC-CRUD
- HDU-1166 敌兵布阵 (树状数组 or 线段树)
- [牛客网,剑指offer,python] 用两个栈实现队列
- ZooKeeper学习概述
- TestLink学习三:发送邮件的两种配置方法
- 635. Design Log Storage System
- 5. 树--二叉树的表示及其遍历
- h2数据库迁移到mysql