一、为什么要生成代理

使用RPC的原则就是像使用本地方法一样,让开发者感觉不到任何的不同。所以就必须把服务代理到本地,常见的方式有三种,动态代理接口静态织入静态编译。三种方式殊途同归,最终都是构建本地数据结构,然后和远程通信。三种方式各有优缺,具体如下:

优缺点 动态代理接口 静态织入 静态编译
优点 动态构建类,灵活、适应性强。 静态代码生成,自定义类参数自动生成,修改较灵活,调用效率高 自定义类参数自动生成,密封性强,安全性高,调用效率高。
缺点 调用效率较低,自定义类参数须自行构建,实现须IL支持,对调用平台有要求,例如:IOS不允许动态类生成,则不可使用。 项目代码管理难统一,强迫症猝死 服务一旦有破坏性升级,则必须重新替换dll,灵活性几乎为0。

为什么RRQM不支持接口代理调用?

【原因一】
RRQM的rpc支持out和ref参数,在使用代理时,效率不高。

【原因二】
RRQM的rpc需要在参数支持调用上下文,所以无法直接用接口调用。

【原因三】
RRQM的rpc支持单次调用的调用配置(例如超时时间,取消调用,序列化方式等)

【原因四】
引用问题,当在服务接口中,使用了其他的项目的数据结构的话,在接口调用项目上也需要引用该项目。太麻烦。

RRQM源文件代理相比接口代理,有什么优缺点?

源文件代理相比接口代理,几乎没什么缺点。有人会觉得接口代理更整洁、方便?实际上源文件代理只会更整洁、方便。

假设一个场景,你需要开发服务器和客户端,这时,你需要做:

  1. 先单独定义一个接口项目
  2. 再定义一个实现项目
  3. 编译接口项目
  4. 引用到客户端

上述步骤中,还不包括,接口项目和实现项目需要引入其他引用的情况,也不包括,接口中包含了其他项目的自定义数据结构。如果包含了的话,客户端还需要引入其他项目。

而且,还需要考虑接口项目的编译目标平台和其他编译参数。最难受的是,如果这些工作,是你和同事合作的话,那可能就是出个bug,同事传你一个dll v1.0版本,再有问题,v1.1修复版,等等。

而最要命的,当属程序集数据泄露。设想一下,如果某个同事在写数据库操作的项目时,把连接信息直接放在了代码里(或某个逻辑),本身如果这个项目只在服务器应用,也没有关系,但是因为你懒,你在接口中使用了该项目的一个数据结构,这就使得你不得不把这个项目一同交给调用方的同事,但你对这些毫无察觉。嗷嚎,黑用户一反编译,直接帮你把数据整理了。

但是如果用RRQM的源代码,那上述的可怕问题根本不用考虑。其次,会更整洁,更方便。

假设相同场景,你需要开发服务器和客户端,这时,你需要做:

  1. 先定义一个服务项目(可以写接口,也能写逻辑,当然也可以分成两个项目)
  2. 编译项目,然后导出代理源代码。
  3. 引用到客户端
  • 不需要考虑数据结构引用问题,因为代理会转写。
  • 不需要考虑编译参数问题,因为客户端拿到的也是源码。
  • 不需要再让同事一次次发你dll,只需要,他启动服务,你更新引用就ok。
  • 不需要怕程序集数据泄露,因为一切都是转写的,而且只转写应用的、公共的部分。

二、从本地获取代理

在开发过程中,如果服务器和客户端,都是我们自己开发的话(在同一个电脑),就可以使用本地代理生成。

调用下列代码,会将已注册的所有服务,导出代理为字符串。

RpcStore是实例,或者是IRpcParser的属性

  1. string code=RpcStore.GetProxyCodes("MyNameSpace"));

【示例1】
将代理字符串,写成.cs文件,然后通过链接的形式,将代码添加到客户端项目。

服务器代码,在服务器执行后,会在运行路径下,生成一个WhisperServers.cs的文件。

  1. File.WriteAllText("WhisperServers.cs", m_service.RpcStore.GetProxyCodes("WhisperServers"));

然后打开需要引入的客户端解决方案。选择需要添加代理的项目,依次执行:

右击项目=》添加=》现有项

然后选择服务器生成的.cs文件,选择“添加”的下拉框,选择“添加为连接”。
image.png
image.png

最后确认文件被正确添加为链接。
image.png

这样,每次当服务有更新的时候,只需要启动一下服务器,代理就会自动刷新。

实际上在RpcStore完成服务注册解析器添加以后,调用GetProxyInfo,输入代理类型、即可获得代理信息,然后再通过CodeGenerator.ConvertToCode方法,转换为可以直接编译的代码。
此时,你可以复制、或者直接把代理代码写成源代码(cs文件)。
然后你可以把这个代码引入到客户端

  1. //或者直接本地导出代理文件。
  2. ServerCellCode[] codes = rpcStore.GetProxyInfo(RpcStore.ProxyAttributeMap.Values.ToArray());
  3. string codeString = CodeGenerator.ConvertToCode("RRQMProxy", codes);

亦或者,为防止篡改生成的代码,不想把代理代码直接投入使用,那可以考虑将代码单独编译成dll,然后将编译的程序集加载到客户端。

三、从远程获取代理

往往,在开发时,服务器和客户端可能是由多个人共同合作完成的,那么这个时候,如果还是以本地的方式获取代理的话,沟通往往会比较麻烦,所以如果能远程获取的话,就会事半功倍。

如果需要远程获取代理,就必须在服务器RpcStore初始化后,调用ShareProxy分享代理文件,代理分享和实际调用没有任何关系,分享代理的主要作用就是减轻编码人员的负担,所以建议代理端口**不要**一直打开,仅当客户端代理文件需要更新时打开即可,其他时候可以调用StopShareProxy停止分享。示例中将以8848端口分享端口。

  1. rpcStore.ShareProxy(new IPHost(8848));

然后需要依靠插件(或程序),直接获取服务,然后将代理源文件植入项目中。具体步骤如下:

a).下载、安装RRQMRPCVSIX插件
【下载】
访问以下任意连接下载插件,然后安装“RRQMRPCVSIX.vsix”即可。

b).下载、运行RRQMRPCTool工具
如果完成了a步骤,则可以忽略本步骤。如果VS版本太低,或不想安装VS插件,那下载 RRQMRPCTool运行工具即可。
解压后直接运行exe程序,界面和c步骤一致。
1. 生成,获取代理 - 图4
c).获取代理
【插件使用】

  1. 安装(下载)完成后,右击项目,即可见“重新引用RPC”菜单条目。
  2. 点击,填入参数,确定即可。
  3. 完成后,项目中会多出“RRQMRPC”文件夹,里面的文件既是代理文件。

【RRQMRPCTool.exe使用】

  1. 运行exe后,需要先选择“目标项目”,选择到客户端项目的.csproj文件。
  2. 然后,填入参数,确定即可。
  3. 完成后,项目中会多出“RRQMRPC”文件夹,里面的文件既是代理文件。

【目标Url】

  1. http://127.0.0.1:8848/proxy?proxy=all&namespace=RRQMProxy

使用url,浏览器也能获取代理。

1. 生成,获取代理 - 图5image.png1. 生成,获取代理 - 图7

1.5 参数说明

参数 说明
目标项目
1. 在VS插件中,该内容是自动识别的,不需要,也无法修改。
1. 在exe运行工具是,需要手动选择.csproj项目文件。然后会自动识别。
存放目录
1. 该选项默认为RpcProxy,意味着会在项目路径下,创建一个RpcProxy文件夹,然后存放所有代理文件。
1. 当手动选择其他路径时,最终仍然会以RpcProxy结尾。
目标地址 目标地址是个http的URL,这也是最重要的远程访问信息。其中支持以下参数:
- proxy:代理类型,如果想获取TouchRpc的代理,传入TouchRpc即可,也可以是JsonRpc,多个参数用逗号隔开。输入all时,表示全部代理。
- namespace:命名空间,在VS插件或exe工具中,也是文件名。

视频教程

点击查看【bilibili】