昨天我的一个 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

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

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, , 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

将app接口服务器改为dotnet core承载的更多相关文章

  1. dotnet Core 调用HTTP接口,系统大量CLOSE_WAIT连接问题的分析,尚未解决。

    环境: dotnet core 1.0.1 CentOS 7.2 今天在服务器巡检的时候,发现一个服务大量抛出异常 异常信息为: LockStatusPushError&&Messag ...

  2. 本地Docker Jenkins构建dotnet core web应用到Linux服务器 Docker上

    1.准备工作 环境 本地: Windows.Docker 代码仓库:Git 服务器:Linux.Docker 前提准备 创建个有dockerfile文件的dotnet core 3 web项目 新建一 ...

  3. 用dotnet core 搭建web服务器(一)http server

    环境说明 dotnet core,开发需要安装dotnetcore sdk,运行需要安装 dotnetcore runtime 运行目前几乎支持所有常见平台 开发推荐windows10 平台 首先安装 ...

  4. dotnet core 使用 sqlite 部署到 Centos 服务器

    原文:dotnet core 使用 sqlite 部署到 Centos 服务器 本文告诉大家如何创建一个 asp dotnet core 程序,这个程序使用 sqlite 保存,部署程序到 Cento ...

  5. win10 uwp 使用 asp dotnet core 做图床服务器客户端

    原文 win10 uwp 使用 asp dotnet core 做图床服务器客户端 本文告诉大家如何在 UWP 做客户端和 asp dotnet core 做服务器端来做一个图床工具   服务器端 从 ...

  6. vs2017 js cordova + dotnet core 开发app

    原文:vs2017 js cordova + dotnet core 开发app 1.记得在index.html加入 <meta http-equiv="Content-Securit ...

  7. dotnet core swagger filter 隐藏接口和显示枚举描述

    dotnet core 2.2开发项目中,常会使用Swagger UI来生成在线Api文档. 某些接口不想放到Swagger中可以这样写Filter: /// <summary> /// ...

  8. publish dotnet core angular spa app to docker

    公司一个使用Angular开发的应用准备下个版本使用.Net Core开发后台, 刚好可以用到.Net Core Angular Spa模板, 而且最近也在学习Docker, 于是就想把它融汇贯通, ...

  9. 用dotnet core搭建web服务器(三)ORM访问数据库

    访问传统sql数据库,大家以前都是用sql语句去查询.这些年流行orm方法 ORM是对象关系映射的简拼,就是用一个对象(class)去表示数据的一行,用对象的成员去表述数据的列 dotnet 官方很早 ...

随机推荐

  1. 警惕System.Environment.CurrentDirectory 获取当前目录

    最近工作中,要做个客户端提醒的小工具:winform程序自然少不了要读取和应用程序同一个目录的配置文件(不是exe.config文件): 要读取当前应用程序所在目录我立马想到了System.Envir ...

  2. jquery判断按钮是否被选中了

    <script type="text/javascript"> function genjin_view2(elm){ if($(elm).attr("che ...

  3. shell中source与sh区别

    shell中使用source conf.sh,是直接运行conf.sh的命令,不创建子shell,类似与html中include,而sh是则创建子shell, 子shell里面 的变量父shell无法 ...

  4. php 多维数组简化(递归)

    <?php $a=[ 'a'=>['d'=>['aa'=>1,'bb'=>2,'cc'=>3]], 'b'=>['f'=>['dd'=>4,'ee ...

  5. 【Android Developers Training】 52. 打印照片

    注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...

  6. CSS 基础

    CSS Cascading Style Sheet 层叠样式表 Css创建: 1.外部样式表(样式表应该以 .css 扩展名进行保存) <head> <link rel=" ...

  7. accp8.0转换教材第7章JavaScript操作DOM对象理解与练习

    程序调试,chrome开发人员工具,DOM操作,节点和节点间的关系,节点信息,操作节点,获取元素 一.单词部分 ①alert警告②prompt提示③parentNode父节点④childNode子节点 ...

  8. laravel5.4+vue+element-ui配置及简单使用

    前言:网上能找到的关于这个方面的教程实在是太少啦,所以踩了好多坑,特意来分享一下,原创哦.想要打包带走的小伙伴还请注明出处

  9. ssh自动化出现的莫名报错

    代码如: ssh -q user@host <<EOF localhost EOF 会出现提示如: Pseudo-terminal will not be allocated becaus ...

  10. hdu2410(水)

    题意 如果两个数字除了带问号的位以外都相同,我们称这两个数可以相互匹配 给你两个数,其中第一个数字里有一些问号,问有多少个大于第二个数的数字可以和第一个数字匹配 一开始懒得读题,到网上搜题意,结果居然 ...