将app接口服务器改为dotnet core承载_.NET_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > .NET > 将app接口服务器改为dotnet core承载

将app接口服务器改为dotnet core承载

 2017/8/11 13:31:20  木屐镇人  程序员俱乐部  我要评论(0)
  • 摘要:昨天我的一个app的接口服务器挂掉了,国外的小鸡意外的翻车,连同程序和数据一起,猝不及防。我的服务端程序是asp.netmvc,小鸡是256M的内存跑不了windows系统,装的mono。服务器用的jexus,但是还有一个apache+php+mysql的全家桶占用了80端口,所以这个接口是通过apache反向代理的。这样一来本来环境就很复杂了,我ubuntu16.04装mono下载了差不多700mb的数据,安装后体积更大,简直太不环保了,只有不到10G的硬盘。于是狠下心将服务器端程序重写
  • 标签:net 服务器 服务 接口 APP

昨天我的一个 app 的接口服务器挂掉了,国外的小鸡意外的翻车,连同程序和数据一起,猝不及防。我的服务端程序是 asp.net mvc ,小鸡是 256 M 的内存跑不了 windows 系统,装的 mono 。服务器用的 jexus,但是还有一个 apache+php+mysql 的全家桶占用了 80 端口,所以这个接口是通过 apache 反向代理的。

这样一来本来环境就很复杂了,我 ubuntu 16.04 装 mono 下载了差不多700 mb 的数据,安装后体积更大,简直太不环保了,只有不到 10G 的硬盘。于是狠下心将服务器端程序重写,其它快餐语言我不会,据说 nodejs 和 python 会很快,部署也方便。但我还是用我的大 C#,好在现在有 dotnet core 了,也给大家安利一发,它是一个模块化的开发栈,也是未来的所有.NET平台的基础,横跨 Windows、Linux、OSX 三大主流系统。

因为我的接口比较简单,主要是输出 json 以及几个静态页面。所以不需要创建 web 项目,我并不想让他寄宿在服务器软件上运行,自己实现 Http 监听处理请求即可,不过这些 dotnet core 已经为你准备好了一个 Server.Kestrel,不需要自己造轮子。

关于 Server.Kestrel 可以参考这篇文章 ,更多的还是官方更详细,传送门 ,以及源码和示例:https://github.com/aspnet/KestrelHttpServer

在包管理控制台执行安装:

class="brush:csharp;gutter:false;">PM>  Install-Package Microsoft.AspNetCore.Server.Kestrel -Pre

另外,如果需要静态文件支持,还需要下面的库:

PM>  Install-Package Microsoft.AspNetCore.StaticFiles -Pre

使用很简单,在 Main 方法里实例化一个 WebHostBuilder 并调用 run 方法就可以,其他的都是配置。

var host = new WebHostBuilder()
    .UseKestrel()
    .UseUrls("http://*:5001")
    .UseContentRoot(Directory.GetCurrentDirectory())
    .UseStartup<Program>()
    .Build();
host.Run();

处理请求简直不要太简单:

app.Run(async (context) =>
{
    byte[] data = Encoding.UTF8.GetBytes("hello world");
    await context.Response.Body.WriteAsync(data, 0, data.Length).ConfigureAwait(false);
});

但是显然不够强大,无法处理 url 路由,接下来写一个抽象类处理 http 请求。

abstract class HandlerBase
{
    public abstract void Process(HttpContext context);
}

这里可以用一个 Dictionary<string,Handler> 保存路由:

_routes = new Dictionary<string, HandlerBase>();
_routes.Add("/home/hello", new Hello());
_routes.Add("/test/demo", new Demo());

Hello 这个类需要继承 HandlerBase 抽象类,重写 Process 方法:

class Hello : HandlerBase
{
    public async override void Process(HttpContext context)
    {
        byte[] data = Encoding.UTF8.GetBytes("hello world");
        await context.Response.Body.WriteAsync(data, 0, data.Length).ConfigureAwait(false);
    }
}

这样就避免了为了处理路由写一堆 if else,扩展性比较好,根据 url 路径找到对应的 HandlerBase 的实现,并调用 Process 处理请求。

app.Run(async (context) =>
{
    HandlerBase handler = null;
    _routes.TryGetValue(context.Request.Path.ToString().ToLower(), out handler);
    if (handler != null) handler.Process(context);
    else
    {
        byte[] data = Encoding.UTF8.GetBytes("HTTP 404");
        await context.Response.Body.WriteAsync(data, 0, data.Length).ConfigureAwait(false);
    }
});

 

浏览器打开效果  

然后就是静态文件的处理问题,建议放一个文件夹存放静态文件,比如创建 dotnet core web 程序时,会有一个 www 的文件夹。

Kestrel 处理静态内容也很简单:

app.UseStaticFiles(new StaticFileOptions()
{
    FileProvider = _fileProvider,
    RequestPath = ""
    
});

FileProvider 是必须是实现了 IFileProvider 的类。

IFileProvider _fileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "www"));

由于 RequestPath 是空字符串,这样一来只要访问 /abc.txt 就会直接映射到 www 目录下的 abc.txt 文件并原始返回。

发布项目后会产生一个 PublishOutput 文件夹,将里面的内容复制到主机 /home/test 目录中。要运行这个项目还需要在服务器安装 dotnet core ,这并不需要再原代码重新编译了,怎么安装可以参考官网。

执行下面命令运行你的项目,如果你的项目叫 demo ??:

dotnet demo.dll

启动程序

最后的最后,如果想深入学习,不要只是执行个 Hello World,绝知此事要躬行!

发表评论
用户名: 匿名