跳到主要内容
版本:1.3.9

从服务端生成代理

一、生成代理

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

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

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

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

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

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

var service = new TcpTouchRpcService();
var config = new TouchSocketConfig()//配置
.SetListenIPHosts(new IPHost[] { new IPHost(port) })
.ConfigureContainer(a =>
{
a.AddConsoleLogger();
a.AddFileLogger();
})
.ConfigureRpcStore(a =>
{
a.RegisterServer<MyRpcServer>();//注册服务

#if DEBUG
File.WriteAllText("../../../WhisperServers.cs", a.GetProxyCodes("WhisperServers",new Type[] { typeof(TouchRpcAttribute) }));
#endif
})
.SetVerifyToken("TouchRpc");

service.Setup(config)
.Start();

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

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

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

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

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

注意

上述操作仅对客户端服务器都在同一电脑上开发时才有效。

提示

当不在同一个电脑上时,可将代理信息写成文件,直接发给客户端开发电脑。亦或者,为防止篡改生成的代码,不想把代理代码直接投入使用,那可以考虑将代码单独编译成dll,然后将编译的程序集发送。

提示

上述行为,均是导出所有已注册的服务,当需要直接生成多个不同代理的源码时,可通过CodeGenerator静态类的相关方法直接生成。例如:

string codes=CodeGenerator.GetProxyCodes("Namespace",new Type[]{typeof(RpcServer) },new Type[] { typeof(TouchRpcAttribute)});

二、代理类型添加

通过之前的学习,大家可能大概明白了,在Rpc中,客户端与服务器在进行交互时,所需的数据结构不要求是同一类型,。所以在声明了服务以后,服务中所包含的自定义类型,会被复刻成结构相同的类型,但是这也仅仅局限于参数与服务相同程序集的时候。如果服务中引入了其他程序集的数据结构,则不会复刻。

但是,往往在服务端开发中,会引入其他程序集,例如,我们习惯在项目中建立一个Models程序集,用于存放所有的实体模型,那是不是意味着客户端也必须引入这个程序集才能调用呢?没别的方法了?

答案,当然不是!!!

Rpc规范了两种方式来添加实体模型的复刻。

2.1 直接添加代理类型

在服务注册之前,任意时刻,可调用CodeGenerator.AddProxyType静态方法,添加代理类型,同时可传入一个bool值,表明是否深度搜索,比如,假如ProxyClass1中还有其他类型,则参数为True时,依然会代理。

CodeGenerator.AddProxyType<ProxyClass1>();
CodeGenerator.AddProxyType<ProxyClass2>(deepSearch:true);

或者直接按程序集添加

CodeGenerator.AddProxyAssembly(typeof(Program).Assembly);

2.2 通过特性标记添加

在需要代理的类上面声明RpcProxy标签,然后也可以重新指定代理类名。

[RpcProxy("MyArgs")]
public class Args
{
}
提示

该场景可用于代理其他dll的自定义类型。

三、代理类型排除

默认情况下,与声明服务相同的自定义类型,会被代理复刻成结构相同的类型。但是有时候,我们希望服务端与客户端公用一个dll,所以就不需要复刻,那么可以排除代理类型。

CodeGenerator.AddIgnoreProxyType(typeof(Program));

或者直接按程序集排除

CodeGenerator.AddIgnoreProxyAssembly(typeof(Program).Assembly);
提示

该场景可用于服务端与客户端公用一个实体dll,例如:当使用MemoryPack序列化的场景。