1. 程式人生 > >基於Asp.net core Kestrel的超迷你http伺服器

基於Asp.net core Kestrel的超迷你http伺服器

  AServer是基於ASP.NET Core Kestrel封裝的一個超迷你http伺服器。它可以整合進你的Core程式裡,用來快速的響應Http請求,而不需要整合整個ASP.NET Core MVC 框架。

一:什麼是ASever?

  AServer就像它的名字一樣,Just a server,它的功能非常簡單,它唯一的功能就是用來對Http請求做出響應。以前我們開發一個.NET程式,比如控制檯程式,Windows服務等,如果需要對外提供介面,我們通常會在程式裡整合WCF,使用WCF對外提供RPC介面。但是現在是.NET Core的時代,我們已經沒有辦法選擇WCF了。而且這些需求往往很簡單,只是想要對外提供幾個介面,查詢一些資料,或者觸發一些功能,如果我們整合整個ASP.NET Core MVC框架又覺得是殺雞用牛刀的感覺。這個時候你或許可以選擇AServer。AServer很簡單,它僅僅是一個dll,這或許正是你想要的。

二:使用AServer

  如何使用AServer呢,非常簡單,讓我們看幾個示例程式碼就明白了。假設我們現在有個跑定時任務的控制檯程式,這個程式需要對外提供3個Http介面:

  1.查詢所有任務

  2.新增一個任務

  3.刪除一個任務

  下面演示如何使用AServer來實現這3個介面。

  1.新建一個Core的控制檯程式

  

  2.從nuget安裝AServer

  

  3.例項化一個Server

  直接new一個Server物件,它預設會監聽本地5000埠。

      static void Main(string[] args)
        {
            var server  = new Agile.AServer.Server();
        }

  4.實現查詢所有任務介面

  該介面的請求地址為/api/tasks,請求方法為GET,返回任務列表陣列。

           server.AddHandler(new HttpHandler()
            {
                Method = "GET",
                Path = "/api/tasks",
                Handler = (req, resp) =>
                {
                    return resp.Write("['Task1','Task2','Task3']");
                }
            });

  5.實現新增任務介面

  該介面的請求地址為/api/tasks,請求方法為POST,如果新增成功則返回文字"ok"。

            //新增任務
            server.AddHandler(new HttpHandler()
            {
                Method = "POST",
                Path = "/api/tasks",
                Handler = (req, resp) =>
                {
                    var task = req.BodyContent;
                    Console.WriteLine(task);

                    return resp.Write("ok");
                }
            });

  6.實現刪除任務介面

  該介面的請求地址為/api/tasks/:taskId,請求方法為DELETE,如果刪除成功則返回文字"ok"。

            //刪除任務
            server.AddHandler(new HttpHandler()
            {
                Method = "DELETE",
                Path = "/api/tasks/:taskId",
                Handler = (req, resp) =>
                {
                    var taskId = req.Params.taskId;
                    Console.WriteLine("delete "+taskId);

                    return resp.Write("ok");
                }
            });

  7.啟動伺服器

  呼叫Server.Run()方法啟動伺服器。

 //啟動伺服器
            server.Run();

            Console.WriteLine("Task server is running now .");
            Console.Read();

  8.測試

  至此,演示程式碼編寫完了。執行這個控制檯程式,然後用postman來測試下這3個介面,是否能響應我們預期的結果。

  

  測試查詢任務介面

  

  測試新增任務介面

  

  測試刪除任務介面

  

  可以看到我們對這3個介面的測試都返回了預期的值,說明AServer正確的響應了我們的請求。

  9.通過繼承HttpHandlerController實現介面

  另外,還可以通過繼承HttpHandlerController來處理http請求。該方法更接近ASP.NET MVC慣用的方法。編寫一個class繼承自HttpHandlerController,對裡面的方法新增[HttpHandler] attribute來指定請求地址跟方法。需要注意的是裡面的方法我們約定了簽名:Task (Reqeust,Response)。

  下面的程式碼演示瞭如果通過繼承HttpHandlerController來實現一系列汽車資訊管理的api介面:

 public class ApiController : HttpHandlerController
    {
        public class car
        {
            public string id { get; set; }
            public string name { get; set; }
        }

        [HttpHandler("/api/cars", "GET")]
        public Task GetAllCars(Request req, Response resp)
        {
            List<car> cars = new List<car>();
            cars.Add(new car { name = "ae86" });
            cars.Add(new car { name = "911" });

            var json = JsonConvert.SerializeObject(cars);

            return resp.WriteJson(json);
        }

        [HttpHandler("/api/cars/:name", "GET")]
        public Task GetCar(Request req, Response resp)
        {
            var name = req.Params.name;

            List<car> cars = new List<car>();
            cars.Add(new car { id="001", name = "ae86" });
            cars.Add(new car { id="002",name = "911" });

            var car = cars.FirstOrDefault(c => c.name == name);
            if (car != null)
            {
                var json = JsonConvert.SerializeObject(car);
                return resp.WriteJson(json);
            }
            else
            {
                return resp.Write("NotFound", HttpStatusCode.NotFound, null);
            }
        }

        [HttpHandler("/api/cars","POST")]
        public Task AddCar(Request req, Response resp)
        {
            var car = req.Body<car>();
            //mock return id
            var json = JsonConvert.SerializeObject(car);
            return resp.WriteJson(json);
        }

        [HttpHandler("/api/cars/001", "PUT")]
        public Task UpdateCar(Request req, Response resp)
        {
            var car = req.Body<car>();
            //mock return id
            var json = JsonConvert.SerializeObject(car);
            return resp.WriteJson(json);
        }

        [HttpHandler("/api/cars/001","DELETE")]
        public Task DeleteCar(Request req, Response resp)
        {
            //delete car
            //...

            return resp.WriteJson("ok");
        }
    }  。。。  //載入ApiController  server.AddController<ApiController>();

  10.Request/Response

  通過上面的演示程式碼,不難發現,AServer對Http請求的處理都封裝在HttpHandler物件中。HttpHandler類有3個屬性,Method,Path,Handler。Method表示Http請求的方式,Path表示請求的路徑,Handler是一個Func,業務邏輯就寫在這裡。Handler的這個Func的方法簽名為Task (Request,Response)。

其中Request封裝了本次Http請求的請求部分的引數,它會解析Http請求,把headers,queryStrings,params解析成dynamic物件,所以呼叫引數的時候跟寫JavaScript類似,如:

var name = req.Params.name;
var id = req.Query.id;
var contentType = req.Header.contentType;

Response則封裝了幾個Write方法,用來寫響應的內容,狀態碼,Header等內容,如:

resp.Write("ok");
resp.Write("NotFound", HttpStatusCode.NotFound, null);
var headers = new List<KeyValuePair<string, string>>();
headers.Add(new KeyValuePair<string, string>("Content-Type", "charset=utf-8"));
resp.Write($"user 001 be deleted .", HttpStatusCode.OK, headers);
resp.WriteJson("{name:'kklldog'}");

三:總結

  對於AServer的介紹也差不多了。希望對同學們有幫助。AServer雖然功能很簡單,就是對Http請求做出響應。但是我也可以說AServer的功能很強大,因為它能對Http請求做出響應。因為從Http的本質上來說,AServer幾乎可以實現所有基於Http的功能。我們可以用它來實現restful api,可以用來實現各種管理系統,可以用來實現cms系統。。。

  不管使用ASP.NET MVC或者JSP或者node express等web框架開發bs/web系統的時候其實套路都是一樣的,概況一下就這麼幾步:

  1.攔截請求(路由)

  2.解析請求攜帶的引數(url,headers,querystrings,body等)

  3.根據引數處理業務(查資料,持久資料等)

  4.根據業務處理結果做出響應(html,json,xml等)

  我們只要瞭解這個套路,不管用什麼技術,什麼框架,其實都是一樣的,只要查下api,弄明白怎麼獲取http請求的引數,怎麼做出響應。AServer也實現了這個套路。如果有心的話,對AServer實現過濾器,引數繫結,檢視引擎等功能,那基本上就是一個簡易的mvc框架了。當然如果你的業務複雜,請選用ASP.NET Core MVC,它功能強大,效能強悍;如果你只是需要實現幾個簡單的Http介面,可以考慮AServer來實現。