一個.net開發的rcp框架,rpcoverhttp

項目地址 https://github.com/kissstudio/RpcOverHttpgit

RpcOverHttp

一個基於.NET接口的rpc框架,使用http協議。
接口/實現及其方法相似於asp.net mvc的controller/action樣式,但更易於客戶端使用。github

特性

  • 基於接口, 讓你專一於業務
  • 異步支持, 經過提供Task/Task< T> 做爲方法返回類型。
  • 依賴注入, 在服務器和客戶端封裝ioc容器,提供類型和對象註冊的方法。
  • 經過你本身或框架內置的默認的實現控制調用認證數據序列化
  • 使用內置的protobuf serializer序列化請求參數,使用json serializer序列化請求元數據(RpcHead, 包含接口方法路由信息)。
  • 使用服務器端異常包裝,客戶端在收到服務器端錯誤時將拋出RpcException。
  • 支持self host 和iis集成
  • 支持.NET事件,由websocket驅動(使用iis-集成時要求Windows8,Server2012,及以上)。
  • 支持https,在自託管模式下自動生成https自簽名證書。
  • 對象自動釋放 當使用Stream或從IDisposible繼承的其餘對象,框架將自動調用IDisposible.Dispose。

如何使用?

1)在MyInterface.dll中定義接口

public interface IRpcServiceSample
    {
        string GetUserName();
        bool IsUserAuthenticated();
        void TestAccessDeniend();
        void TestAccessOk();
        Task TestRemoteTask();
        Task<string> TestRemoteTaskWithResult();
        Task<string> TestRemoteAsyncTaskWithResult();
    void UploadStream(Stream stream, string fileName);
        Stream DownloadStream(string fileName);
    }

2)在MyImpl.dll中實現接口,引用RpcOverHttp.dll,MyInterface.dll

RpcService僅用於訪問用戶信息。若是不使用User對象能夠刪除web

public class RpcServiceSample : RpcService, IRpcServiceSample
    {
        public RpcServiceSample()
        {
        }

        public string GetUserName()
        {
            return this.User.Identity.Name;
        }

        public bool IsUserAuthenticated()
        {
            return this.User.Identity.IsAuthenticated;
        }

        public void TestAccessOk() { }

        [Authorize]
        public void TestAccessDeniend() { }

        public Task TestRemoteTask()
        {
            return Task.Delay(5000);
        }

        public Task<string> TestRemoteTaskWithResult()
        {
            return Task.Delay(5000)
                .ContinueWith(x => ("remote task completed."));
        }

        public async Task<string> TestRemoteAsyncTaskWithResult()
        {
            return await new StringReader("abc").ReadLineAsync();
        }
    
        public void UploadStream(Stream stream, string fileName)
        {
            var fs = File.Open(fileName, FileMode.Create);
            stream.CopyTo(fs);
            fs.Dispose();
        }

        public Stream DownloadStream(string fileName)
        {
            var fs = File.Open(fileName, FileMode.Open);
            return fs;
        }
    }

3)在控制檯應用程序項目中建立測試服務,引用RpcOverHttp.dll,MyInterface.dll和MyImpl.dll

public static void Main(string[] args)
        {
            var url = "http://127.0.0.1:8970/";
            RpcServer server = new RpcServer();
            server.Register<IRpcServiceSample, RpcServiceSample>();
            server.Start(url);
            Console.ReadLine();
        }

4)在控制檯應用程序項目中建立測試客戶端,引用RpcOverHttp.dll,MyInterface.dll

static void Main(string[] args)
        {
            var client = RpcClient.Initialize("http://localhost:8970/");
            var sample = client.Rpc<IRpcServiceSample>();
            var username = sample.GetUserName();
            Debug.Assert(username.Equals("Anonymous"));
            Console.WriteLine("GetUserName ok");
            var isAuthenticated = sample.IsUserAuthenticated();
            Debug.Assert(isAuthenticated.Equals(false));
            Console.WriteLine("IsUserAuthenticated ok");
            sample.TestAccessOk();
            Console.WriteLine("TestAccessOk ok");
            try
            {
                sample.TestAccessDeniend();
            }
            catch (Exception ex)
            {
                Debug.Assert(ex.GetType().Equals(typeof(RpcException)));
                Console.WriteLine("TestAccessDeniend ok");
            }
            sample.TestRemoteTask().Wait();
            var x = sample.TestRemoteTaskWithResult().Result;
            Debug.Assert(x.Equals("remote task completed."));
            Console.WriteLine("TestRemoteTaskWithResult ok");
            Task.Run(async () =>
            {
                var y = await sample.TestRemoteAsyncTaskWithResult();
                Debug.Assert(y.Equals("abc"));
                Console.WriteLine("TestRemoteAsyncTaskWithResult ok");
            });
            var fsup = File.Open("testupload.bin", FileMode.Create);
            int lines = 100;
            var sw = new StreamWriter(fsup);
            while (lines-- > 0)
            {
                sw.WriteLine(string.Concat(Enumerable.Range(0, 10000)));
            }
            fsup.Position = 0;
            Console.WriteLine("uploading a file, size=" + new ByteSize(fsup.Length));
            sample.UploadStream(fsup, "testfile.temp");
            Console.WriteLine("UploadStream ok");
            Console.WriteLine("downloading the file...");
            var ms = sample.DownloadStream("testfile.temp");
            Console.WriteLine("DownloadStream ok");
            var fsdown = File.Open("testdownload.bin", FileMode.Create, FileAccess.Write);
            ms.CopyTo(fsdown);
            Debug.Assert(fsup.Length.Equals(fsdown.Length));
            Console.WriteLine("UploadStream.Length is equal to DownloadStream.length? ok");
            fsup.Close();
            fsdown.Close();
            ms.Dispose();
            Console.ReadLine();
        }

支持的參數類型

  • .NET基礎類型和String,List< T>,Enum
  • Stream
  • 僅使用上述類型的類。
  • 上述類型或僅使用上述類型的類的數組或泛型List

限制

  • 請參閱支持的#argument類型
  • 不支持嵌套Task做爲返回類型。

https

self host模式:json

  • 在服務器端,若是你使用https網址,當服務器啓動時,框架將自動生成一個自簽名證書文件對(私鑰將安裝到系統(LocalMachine-> Personal),公鑰將保存在工做目錄下供客戶使用)
  • 在客戶端,將服務端導出的證書公鑰文件提供給initialize方法。
public static RpcClient Initialize(string url,string cerFilePath,WebProxy proxy = null)

要從新生成證書文件對,請從系統中刪除證書(LocalMachine-> Personal)。證書名稱爲「RpcOverHttp」數組

iis-integration模式:服務器

  • 在服務器端,使用iis管理器選擇證書文件。
  • 在客戶端,當ssl服務器證書檢查出錯時,將調用RpcClient.ServerCertificateValidationCallback。只須要像使用HttpWebReqeust.ServerCertificateValidationCallback同樣處理它。

從版本3.3.0開始支持iis集成,爲在iis上託管rpc服務器提供了http模塊

self host示例:websocket

public class Program
    {
        public static void Main(string[] args)
        {
            var url = ConfigurationManager.AppSettings["urlPrefix"];
            RpcServer server = new RpcServer();
            server.Register<IRpcServiceSample, RpcServiceSample>();
            server.Start(url);
            Console.ReadLine();
        }
    }

iis模塊示例:mvc

//dll name is RpcHost, namespace is RpcHost
    public class RpcWebHostHttpModule : RpcServerHttpModule
    {
        public override void InitRpcServer(IRpcServer server)
        {
            server.Register<IRpcServiceSample, RpcServiceSample>();
        }
    }

在使用iis-integration時,請將服務器項目構建爲dll而不是應用程序(exe)。框架

而後將服務端項目全部輸出dll複製到site的bin文件夾中(若是bin文件夾不存在則建立一個)。asp.net

而後在web.config中註冊http模塊

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.web>
        <compilation debug="true" targetFramework="4.5" />
        <httpRuntime targetFramework="4.5" />
    </system.web>
    <system.webServer>
        <modules>
            <add name="RpcWebHostHttpModule" type="RpcHost.RpcWebHostHttpModule" />
        </modules>
    </system.webServer>
</configuration>
相關文章
相關標籤/搜索