昨天我的一个 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. 避免循环做SQL操作

    经常犯的错误是把一个SQL 操作放置到一个循环中, 这就导致频繁的访问数据库,更重要的是, 这会直接导致脚本的性能低下.以下的例子, 你能够把一个循环操作重置为一个单一的SQL语句. foreach ...

  2. session或memcache过期之后跳转到登陆页面并跳出iframe框架

    <!--在你想控制跳转的页面,比如login.html中的<head>与</head>之间加入以下代码:--> <script> if (window ...

  3. 1.如何安装maven

    [确认]在CMD命令行中输入echo %JAVA_HOME%,查看JAVA_HOME是否配置.在CMD命令行中输入java -v,查看jdk是否正确安装.   [下载]从http://maven.ap ...

  4. Ext & Java 上存图片 Demo

    Ext & Java 上存图片 Demo Ext <html> <head> <script id="microloader" type=&q ...

  5. 【干货】Chrome插件(扩展)开发全攻略(不点进来看看你肯定后悔)

    写在前面 我花了将近一个多月的时间断断续续写下这篇博文,并精心写下完整demo,写博客的辛苦大家懂的,所以转载务必保留出处.本文所有涉及到的大部分代码均在这个demo里面:https://github ...

  6. 优化js脚本设计,防止浏览器假死

    在Web开发的时候经常会遇到浏览器不响应事件进入假死状态,甚至弹出"脚本运行时间过长"的提示框,如果出现这种情况说明你的脚本已经失控了,必须进行优化. 为什么会出现这种情况呢,我们 ...

  7. AngularJS 和 Bootstrap

    AngularJS Bootstrap AngularJS 的首选样式表是 Twitter Bootstrap, Twitter Bootstrap 是目前最受欢迎的前端框架. 查看 Bootstra ...

  8. (转)ManyToMany注解

    @ManyToMany  注释:表示此类是多对多关系的一边,mappedBy 属性定义了此类为双向关系的维护端,注意:mappedBy 属性的值为此关系的另一端的属性名. 例如,在Student类中有 ...

  9. TP3.2写提交的验证码验证

    把今天掌握的东西整理一下,要不然,我就忘干净了: 今天在做一个企业网站的时候,有一个在线留言的功能,最后提交的时候需要输入验证码.如图下: 当然,特连接的并不是我的后台 好了,开始了,首先我需要把验证 ...

  10. 迭代器 Iterator

    迭代器 Iterator 2016-5-7 可以这样说,迭代器统一了对容器的访问方式. 考虑这样的情景:原本是对着List编码,但是后来发现需要把相同的代码用于Set.我们需要一种不关心容器类型 而能 ...