-
Notifications
You must be signed in to change notification settings - Fork 6
SimCivil.Rpc 说明
Chengzhi Tan edited this page Apr 20, 2018
·
6 revisions
SimCivil使用RPC(Remote Procedure Call)处理服务端和客户端以及(将来)分布式服务间的通信。由于目前.net core
平台上没有很好的RPC框架,因此造轮子自己实现一个。
SimCivil.Rpc
使用Azure/DotNetty作为底层网络框架,利用castle.DynamicProxy 动态生成代理对象,以IoC(Autofac)的方式管理远程服务。
首先对于要实现的服务,需要有一个接口使得服务端和客户端能够对应
public interface ITestServiceA
{
string GetName();
string HelloWorld(string name);
int NotImplementedFuc(int i);
string GetSession(string key);
}
目前只支持不带有泛型、委托等特性的普通方法,不支持属性、事件、字段等成员。可以支持带有Task返回的异步方法。
然后再根据接口实现服务端的具体执行类
public class TestServiceA : ITestServiceA
{
public IRpcSession Session { get; }
public string Name { get; set; }
public TestServiceA(IRpcSession session)
{
Session = session;
}
public string GetName()
{
return Name;
}
public string HelloWorld(string name)
{
Name = name;
return $"Hello {name}!";
}
public int NotImplementedFuc(int i)
{
throw new NotImplementedException();
}
public string GetSession(string key)
{
return Session[key].ToString();
}
}
其中IRpcSession
包含了当前会话的持久化信息,可以在不同服务间共享(目前只有LocalRpcSession
只能在单个服务端内共享)。IRpcSession
可以在构造函数通过注入获取,当客户端断开服务群时销毁。
注意服务中所有触发的异常都可以被自动转发到客户端,之后会设计一种机制选择性的返回异常信息。
随后配置Rpc服务端容器,设定要暴露的服务
var builder = new ContainerBuilder();
builder.UseRpcSession();
builder.RegisterRpcProvider<TestServiceA, ITestServiceA>().InstancePerChannel();
var server = new RpcServer(builder.Build());
server.Bind(9999).Run().Wait();
builder.UseRpcSession()
启用会话功能。除了通过调用builder.RegisterRpcProvider<TestServiceA, ITestServiceA>()
在构造容器时暴露服务,还可以在正常注册容器服务后调用server.Expose<ITestServiceA>()
实现。
### 客户端
客户端也需要服务的接口`ITestServiceA`。
```csharp
using (RpcClient client = new RpcClient())
{
client.Bind(9999).ConnectAsync().Wait();
var name = "test";
var service = client.Import<ITestServiceA>();
Assert.Equal(service.HelloWorld(name), $"Hello {name}!");
Assert.Equal(service.GetName(), name);
}
```
配置方法与服务端相似,随后通过`Import`方法获取代理类。接下来的用法就与调用本地方法一样了。