基于动态代理的WebAPI/RPC/webSocket框架,一套接口定义,多个通讯方式

摘要:
三个API/RPC/webSockets似乎没有任何共同点。在开发过程中,服务器端和客户端的实现代码也非常不同。最近,它们已经被整理好了。通过动态代理的形式,这些发展已被整合。它们都基于统一的接口约束。服务器端实现和客户端调用都基于这种形式。WebAPI/RPC/webSocket只需要定义一组接口,就可以达到一般的效果。示例接口约束publicclassTestObj{publicstringName{get;set;}}

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", "7777777777", "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(805);
            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 = 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;

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", 8015);
            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 = 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;

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框架,一套接口定义,多个通讯方式》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇任务栏-添加我的电脑四维的王坚和三维的阿里互联网汽车下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

翻译:WebApi 认证--用户认证Oauth解析

The Web API v2用户认证模板提供了流行的应用用户认证场景,如.使用本地帐号的用户名密码认账 (包括创建用户、设置和修改密码)以及使用第三方的认证方式,如facebook,google等等– 在本地中包含了外部帐号的连接 所有的这些均通过使用一个OAuth2认证服务进行. To make all that happen the template...

Linux NFS 详解

目录:      1、了解NFS服务      2、NFS主要文件      3、NFS安装      4、NFS配置      5、NFS客户端配置      6、固定NFS端口      7、Windows挂载NFS 1、了解NFS服务       NFS是Network  File System(网络文件系统)。主要功能是通过网络让不同的服务器之间可...

webapi-1 给现有MVC 项目添加 WebAPI

1. 增加一个WebApi Controller, VS 会自动添加相关的引用,主要有System.Web.Http,System.Web.Http.WebHost,System.Net.Http 2. 在App_Start 下创建 WebApiConfig.cs 并注册路由 using System; using System.Collections...

Nginx反向代理WebSocket链接失败问题

问题记录:本地socket测试无误后部署发现 WebSocket connection to "xxx/xxx" failed  解决方案: 在nginx.conf的http模块添加如下内容 map $http_upgrade $connection_upgrade { default upgrade; '' close; } 其...

[源码解析] PyTorch 分布式(16) 使用异步执行实现批处理 RPC

[源码解析] PyTorch 分布式(16) --- 使用异步执行实现批处理 RPC 目录 [源码解析] PyTorch 分布式(16) --- 使用异步执行实现批处理 RPC 0x00 摘要 0x01 前言 1.1 先决条件 1.2 基础知识 1.3 代码 0x02 启动 2.1 总体启动 2.2 启动参数服务器 0x03 参数服务器...

FastAPI 学习之路(四十九)WebSockets(五)修复接口测试中的问题

其实代码没有问题,但是我们忽略了一点,就是我们在正常的开发中,肯定是遇到这样的情况,我们频繁的有客户端链接,断开链接,我们需要统一的管理起来,那么我们应该如何去管理呢,其实这个时候,我们要去声明一个类去管理我们的这些链接。我们应该如何优化呢。 定义一个链接管理类,处理我们所有的链接。 classConnectionManager: def __in...