基于动态代理的WebAPI/RPC/webSocket框架,一套接口定义,多个通讯方式
API/RPC/webSocket三个看起来好像没啥相同的地方,在开发时,服务端,客户端实现代码也大不一样
最近整理了一下,通过动态代理的形式,整合了这些开发,都通过统一的接口约束,服务端实现和客户端调用
基于这样的形式,WebAPI/RPC/webSocket只需要定义一套接口,就能达到通用的效果
示例接口约束
public class TestObj
{
public string Name { get; set; }
}
public interface ITestService
{
void Login();
bool Test1(int a,int? b,out string error);
TestObj Test2(TestObj obj);
}
public class TestService : AbsService, ITestService
{
[LoginPoint]
public void Login()
{
SaveSession("hubro", "", "test");
} public bool Test1(int a, int? b, out string error)
{
var user = CurrentUserName;
var tag = CurrentUserTag; error = "out error";
Console.WriteLine(a);
Console.WriteLine(b);
return true;
} public TestObj Test2(TestObj obj)
{
Console.WriteLine(obj.ToJson());
return obj;
}
}
上面是一个标准接口和接口实现,并继承了AbsService,
Login方法标注了LoginPoint特性,表示登录切入点,调用此接口时首先得调用此方法,方法内SaveSession存储登录状态
Test1方法内使用了CurrentUserName,以获取登录方法保存的Session
特点:
- 通过接口约束服务端和客户端调用,参数定义透明化,out也支持
- 真正的方法远程调用,任意参数类型,个数
- 集成登录认证逻辑,自定义登录认证过程,也可以自定义Session实现
- 集成简单数据签名,不用费心数据安全问题
技术实现:
- Dynamitey实现接口类型代理
- DotNetty实现TCP通讯
- 对象二进制序列化
RPC调用
服务端
var server = new ServerCreater().CreatetRPC();
server.CheckSign();
server.SetSessionManage(new SessionManage());
server.Register<ITestService, TestService>();
server.Start();
CreateRPC是一个扩展方法,引用CRL.RPC获取
SetSessionManage,自定义Session存储,默认是内存里
CheckSign 处理请求时,进行参数签名验证
客户端接口调用
var clientConnect = new RPCClientConnect("127.0.0.1", 805);
clientConnect.UseSign();
var service = clientConnect.GetClient<ITestService>();
label1:
service.Login();
Console.WriteLine("loginOk");
int? a = 1;
string error;
service.Test1(1, a, out error);
Console.WriteLine("error:" + error);
var obj2 = service.Test2(new TestObj() { Name = "test" });
Console.WriteLine("obj2:" + obj2.ToJson());
Console.ReadLine();
goto label1;
客户端先调用login方法进行登录,并记录服务端返回的token
Test1方法将token回传给服务器以验证登录状态,并进行远程调用
当调用了UseSign方法,就会对提交的参数进行签名,签名KEY为登录后服务端返回的TOKEN,服务端同样按此对签名进行比较
动态webApi
同样基于上文结构,接口定义就不粘贴了
服务端定义
var server = new ServerCreater().CreatetApi();
server.CheckSign();
server.SetSessionManage(new SessionManage());
server.Register<ITestService, TestService>();
var listener = new ServerListener();
//listener.Start("http://localhost:809/");//自定义监听
如果宿主是.NET网站 在web.config增加处理module
<system.webServer>
<modules>
<add name="DynamicModule" type="CRL.DynamicWebApi.DynamicModule" />
</modules>
</system.webServer>
如果是单独程序,启动ServerListener即可
客户端调用
var clientConnect = new CRL.DynamicWebApi.ApiClientConnect("http://localhost:53065");
//var clientConnect = new CRL.DynamicWebApi.ApiClientConnect("http://localhost:8022");
clientConnect.UseSign();
var service = clientConnect.GetClient<ITestService>(); label1:
service.Login();
Console.WriteLine("loginOk");
int? a = ;
string error;
service.Test1(, a, out error);
Console.WriteLine("error:" + error);
var obj2 = service.Test2(new TestObj() { Name = "test" });
Console.WriteLine("obj2:" + obj2.ToJson());
Console.ReadLine();
goto label1;
WebSocket
WebSocket是一个比较特殊的方式,常用来做双工通讯的方式,客户端能往服务端发送数,服务端也能往客户端发送据
除去服务端往客户端发数据,也可以采用接口调用的形式实现,在这里,服务端往客户端发送数据,客户端采用了订阅的方式
服务端实现
var server = new ServerCreater().CreatetWebSocket(8015);
server.CheckSign();
server.SetSessionManage(new SessionManage());
server.Register<ITestService, TestService>();
server.Start();
new CRL.Core.ThreadWork().Start("send", () =>
{
var socket = server.GetServer() as CRL.WebSocket.WebSocketServer;
socket.SendMessage("hubro", new socketMsg() { name = DateTime.Now.ToString() }, out string error);
Console.WriteLine("send msg");
return true;
}, 10);
上面演示代码,服务端开启了一个线程,定时往客户端"hubro"发送数据 socket.SendMessage
客户端实现
var clientConnect = new CRL.WebSocket.WebSocketClientConnect("127.0.0.1", );
clientConnect.UseSign();
clientConnect.SubscribeMessage<socketMsg>((obj) =>
{
Console.WriteLine("OnMessage:" + obj.ToJson());
});
clientConnect.StartPing();
var service = clientConnect.GetClient<ITestService>();
label1: service.Login();
Console.WriteLine("loginOk");
int? a = ;
string error;
service.Test1(, a, out error);
Console.WriteLine("error:" + error);
var obj2 = service.Test2(new TestObj() { Name = "test" });
Console.WriteLine("obj2:" + obj2.ToJson());
Console.ReadLine();
goto label1;
clientConnect.SubscribeMessage就是订阅消息了,通过订阅的方式,处理服务端发送的数据
可以看到以上各种形式,服务端实现和客户端调用基本相同,定义的接口能重复使用,做接口通讯效果杠杠的
具体实现方式和细节功能参见源码和demo,已经开源,请自行下载
源码地址:
CRL:
https://github.com/hubro-xx/CRL5
RCP:
https://github.com/hubro-xx/CRL5/tree/master/RPC
WebAPI:
https://github.com/hubro-xx/CRL5/tree/master/DynamicWebApi
WebSocket:
https://github.com/hubro-xx/CRL5/tree/master/WebSocket
基于动态代理的WebAPI/RPC/webSocket框架,一套接口定义,多个通讯方式的更多相关文章
- .NET 下基于动态代理的 AOP 框架实现揭秘
.NET 下基于动态代理的 AOP 框架实现揭秘 Intro 之前基于 Roslyn 实现了一个简单的条件解析引擎,想了解的可以看这篇文章 https://www.cnblogs.com/weihan ...
- 实现一个简单的基于动态代理的 AOP
实现一个简单的基于动态代理的 AOP Intro 上次看基于动态代理的 AOP 框架实现,立了一个 Flag, 自己写一个简单的 AOP 实现示例,今天过来填坑了 目前的实现是基于 Emit 来做的, ...
- 动态代理到基于动态代理的AOP
动态代理,是java支持的一种程序设计方法. 动态代理实现中有两个重要的接口和类,分别是InvocationHandler(interface),Proxy(class). 要实现动态代理,必须要定义 ...
- mybatis源码学习:基于动态代理实现查询全过程
前文传送门: mybatis源码学习:从SqlSessionFactory到代理对象的生成 mybatis源码学习:一级缓存和二级缓存分析 下面这条语句,将会调用代理对象的方法,并执行查询过程,我们一 ...
- MyBatis学习(三)MyBatis基于动态代理方式的增删改查
1.前言 上一期讲到MyBatis-Statement版本的增删改查.可以发现.这种代码写下来冗余的地方特别多.写一套没啥.如果涉及到多表多查询的时候就容易出现问题.故.官方推荐了一种方法.即MyBa ...
- Java通过Socket和动态代理实现简易RPC框架
本文转自Dubbo作者梁飞大神的CSDN(https://javatar.iteye.com/blog/1123915),代码简洁,五脏俱全. 1.首先实现RpcFramework,实现服务的暴露与引 ...
- JDK动态代理在RPC框架中的应用
RPC框架中一般都有3个角色:服务提供者.服务消费者和注册中心.服务提供者将服务注册到注册中心,服务消费者从注册中心拉取服务的地址,并根据服务地址向服务提供者发起RPC调用.动态代理在这个RPC调用的 ...
- 带你手写基于 Spring 的可插拔式 RPC 框架(一)介绍
概述 首先这篇文章是要带大家来实现一个框架,听到框架大家可能会觉得非常高大上,其实这和我们平时写业务员代码没什么区别,但是框架是要给别人使用的,所以我们要换位思考,怎么才能让别人用着舒服,怎么样才能让 ...
- Java动态代理——框架中的应用场景和基本原理
前言 之前已经用了5篇文章完整解释了java动态代理的原理,本文将会为这个系列补上最后一块拼图,展示java动态代理的使用方式和应用场景 主要分为以下4个部分 1.为什么要使用java动态代理 2.如 ...
随机推荐
- lightoj 1084 - Winter(dp+二分+线段树or其他数据结构)
题目链接:http://www.lightoj.com/volume_showproblem.php?problem=1084 题解:不妨设dp[i] 表示考虑到第i个点时最少有几组那么 if a[i ...
- 2018湖南多校第二场-20180407 Barareh on Fire
Description The Barareh village is on fire due to the attack of the virtual enemy. Several places ar ...
- 单细胞转录组测序技术(scRNA-seq)及细胞分离技术分类汇总
单细胞测序流程(http://learn.gencore.bio.nyu.edu) 在过去的十多年里,高通量测序技术被广泛应用于生物和医学的各种领域,极大促进了相关的研究和应用.其中转录组测序(RNA ...
- Codeforces1093E_Intersection of Permutations
题意 给定两个排列a和b,两种操作,交换b_i和b_j,询问a[l_a...r_a]和b[l_b...r_b]有多少个数相同. 分析 由于给的是排列,保证b的每个数都有a的对应,构造数组c,c[i]表 ...
- mybatis拦截器实现通用权限字段添加
实现效果 日常sql中直接使用权限字段实现权限内数据筛选,无需入参,直接使用,使用形式为:select * from crh_snp.channelinfo where short_code in ( ...
- android 拍照 相册 剪切以及显示功能
一.概述 android的 图片拍照 ,相册选图,以及图片剪切功能可以说非常常用. 尤其是图片上传功能,必然用到此功能. 而公司最近的一个项目中正好用到该功能. 记录下来以便以后再次用到,直接拿来使用 ...
- spring boot的多环境部署
需求:不同的环境有不同的开关属性,比如开发系统,需要关闭短信,微信的通知功能.而演示环境,线上环境则需要打开这些配置. 那么,如何做到呢?--->在properties.application配 ...
- tomcat 中无法添加项目等问题的解决方案
博客地址:http://www.moonxy.com 一.前言 今天新建了一个 maven 项目,添加程序文件之后,发现无法添加项目,然后修改配置,将应用添加到了 tomcat,启动时又报错,解决出现 ...
- jmeter 查看结果树数据分析 优化
1.点击查看结果树,配置 2.筛选功能项
- 如何使用rsync备份
已知3台服务器主机名分别为web01.backup .nfs主机信息见下表: 角色 外网IP(NAT) 内网IP(LAN) 主机名 WEB eth0:10.0.0.7 eth1:172.16.1.7 ...