zoukankan      html  css  js  c++  java
  • 基于Asp.net core Kestrel的超迷你http服务器 ---- AServer

      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,这或许正是你想要的。

    github地址:https://github.com/kklldog/AServer 欢迎star。

    二:使用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来实现。

    出处:https://www.cnblogs.com/kklldog/p/agileaerver.html

    您的资助是我最大的动力!
    金额随意,欢迎来赏!
    款后有任何问题请给我留言。

    如果,您认为阅读这篇博客让您有些收获,不妨点击一下右下角的推荐按钮。
    如果,您希望更容易地发现我的新博客,不妨点击一下绿色通道的关注我。(●'◡'●)

    如果你觉得本篇文章对你有所帮助,请给予我更多的鼓励,求打             付款后有任何问题请给我留言!!!

    因为,我的写作热情也离不开您的肯定支持,感谢您的阅读,我是【Jack_孟】!

  • 相关阅读:
    PAT (Advanced Level) 1060. Are They Equal (25)
    PAT (Advanced Level) 1059. Prime Factors (25)
    PAT (Advanced Level) 1058. A+B in Hogwarts (20)
    PAT (Advanced Level) 1057. Stack (30)
    PAT (Advanced Level) 1056. Mice and Rice (25)
    PAT (Advanced Level) 1055. The World's Richest (25)
    PAT (Advanced Level) 1054. The Dominant Color (20)
    PAT (Advanced Level) 1053. Path of Equal Weight (30)
    PAT (Advanced Level) 1052. Linked List Sorting (25)
    PAT (Advanced Level) 1051. Pop Sequence (25)
  • 原文地址:https://www.cnblogs.com/mq0036/p/13895421.html
Copyright © 2011-2022 走看看