基於動態代理的WebAPI/RPC/webSocket框架

API/RPC/webSocket三個看起來好像沒啥相同的地方,在開發時,服務端,客戶端實現代碼也大不一樣

最近整理了一下,通過動態代理的形式,整合了這些開發,都通過統一的接口約束,服務端實現和客戶端調用

 

先上RPC示例

服務端

接口和接口實現

public interface ITest
        {
            bool login(int? a);
            string Test1(string msg, out string error);
        }
        public class Test : AbsService, ITest
        {
            [LoginPoint]//登錄切入點
            public bool login(int? a)
            {
                SaveSession("user","token");
                return true;
            }
       
            public string Test1(string msg, out string error)
            {
                var user = CurrentUserName;
                var tag = CurrentUserTag;
                error = "error";
           
                return msg;
            }
        }

 

上面是一個標準接口和接口實現,並繼承了AbsService,

Login方法標註了LoginPoint特性,表示登錄切入點,調用此接口時首先得調用此方法,方法內SaveSession存儲登錄狀態

Test1方法內使用了CurrentUserName,以獲取登錄方法保存的Session

服務啓動

var server = new ServerCreater().CreatetRPC(805);
            server.CheckSign();
            server.SetSessionManage(new SessionManage());
            server.Register<ITest, Test>();//服務端註冊接口和接口的實現
            server.Start();

  

CreateRPC是一個擴展方法,引用CRL.RPC獲取

SetSessionManage,自定義Session存儲,默認是內存裏

CheckSign 處理請求時,進行參數簽名驗證

客戶端

客戶端接口定義

    public interface ITest
    {
        bool login(int? a);
        string Test1(string msg,out string error);
    }

  

接口調用

 var clientConnect = new RPCClientConnect("127.0.0.1", 805);
            clientConnect.UseSign();
int? a=null;
            client.login(a);//先登錄認證
string error = "";
                var str = client.Test1("aaa",out error);
                Console.WriteLine($"return:{str} out:{error}");

 

客戶端先調用login方法進行登錄,並記錄服務端返回的token

Test1方法將token回傳給服務器以驗證登錄狀態

當調用了UseSign方法,就會對提交的參數進行簽名,簽名KEY爲登錄後服務端返回的TOKEN,服務端同樣按此對簽名進行比較 

 

特點:

  • 通過接口約束服務端和客戶端調用,參數定義透明化,out也支持
  • 真正的方法遠程調用,任意參數類型,個數
  • 集成登錄認證邏輯,自定義登錄認證過程,也可以自定義Session實現

技術實現:

  • Dynamitey實現接口類型代理
  • DotNetty實現TCP通訊
  • 對象二進制序列化

動態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");
clientConnect.UseSign();
            var service = clientConnect.GetClient<ITestService>();
var str = service.Login("user", "123");
            Console.WriteLine(str);
int? a = 1;
            service.SendData("data",a);

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>();
            var str = service.Login("user", "123");
int? a = 1;
            service.SendData("data", a);

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章