Gorilla源码分析之gorilla/rpc源码分析


本文公众号文章链接:https://mp.weixin.qq.com/s/6ZNJB1Qcwdk0MaC2fWu4ng

本文csdn博客链接:https://blog.csdn.net/screscent/article/details/79663424


Gorilla是一个go语言的web工具箱,包含了很多的模块。本文分析的模块gorilla/rpc:implements RPC over HTTP with codec for JSON-RPC.

代码目录如下:

 

一、实例

扫描二维码关注公众号,回复: 2867104 查看本文章

来自官网http://www.gorillatoolkit.org/pkg/rpc的例子


首先New了一个Server

然后在Server中注册了Codec

接着注册了rpc service


上面是具体的rpc service

github.com/gorilla/rpc/server.go


上面有两个东西,codecs,services。后面先分析这两个部分。

二、Codec

我们从简单的入手,先看看Codec

在github.com/gorilla/rpc/server.go,对Codec接口的定义如下


有两个接口:

1、        生成CoedcRequest的接口

2、        CodecRequest接口

那么我们来看看

github.com/gorilla/rpc/json/server.go


Codec接口

按照接口来看,很简单,只是NewRequest种封装了newCodecRequest

继续看源码


通过读取http.Request中的内容,然后经过json解析结构体CodecRequest,其中封装了serverRequest结构体

接下来,我们看看这个结构体


很简单的两个结构体 serverRequest和serverResponse。就不多解释了

继续看CodeRequest的实现的接口


之前通过json解析的Method内容保存在serverRequest结构体中。

在serverRequest中的Params为json.RawMessage,所以需要继续解析params

WriteResponse则相反,将传入的数据,封装到serverResponse结构体中,然后通过json编码,然后写入到http.ResponseWriter中。

三、rpc Service

在实例中,我们看到注册了Codec之后,就注册了Service。那么Service是怎么保存的

github.com/gorilla/rpc/map.go


ServiceMap,就是一个service集合。在实例中,注册的是一个HelloService


Service中有两个部分。

1、        name、rcvr、rcvrType

name其实就是一个标识,Service的名字

rcvr、rcvrType是service的信息,在实例中就是HelloService。

2、        methods。这一部分看ServiceMethod结构体,很直白,就是一个method的信息。对应的就是HelloService类所包含的方法

类名是只有一个的,而类的方法是可以有多个的。这就是为什么分为这两个部分。

注册部分:

Setup service。其中主要是name的操作,当name为空的时候,则直接用rcvr的名字。这部分,主要是第一部分的设置

 

中间代码略


Setup methods。直接遍历类所包含的method,然后将其信息,放到methods这个map中。

Add to the map

将解析好的service信息,放入到serviceMap中。

整个流程很直接,清晰。

看完了注册,看看上面的get函数。先对method拆分成两个部分,一个是类名或服务名部分,一个是方法部分。然后分别进行类名或服务名的查找(图中152行)。然后根据方法名进行查找(图中158行)

至此service部分讲解完。

 

四、rpc server部分

直接看代码吧

github.com/gorilla/rpc/server.go


其中最主要的两部分已经讲解过了


这个是初始化

初始化Codec

这个是注册服务。这个部分也介绍过了。

现在直接进入入口

上面就是获取Codec,在实例中是json,这个具体部分已经解释过了

看源码中的英文注释,解释的很清楚。

创建code Request

然后获取Service 和method

再接着是decode args。

上面,可以忽略,不常用。

这里进入正题,调用rpc函数。这里面有一个flag poassReq,差别在于注册的rpc函数,是否要传入r *http.Request参数。

最后就是将reply通过codec编码发出去。

到这里整个流程就结束了。

龚浩华

月牙寂道长

QQ 29185807

2018年03月22日

第一时间获取文章,可以关注本人公众号:月牙寂道长,也可以扫码关注



猜你喜欢

转载自blog.csdn.net/screscent/article/details/79663424