65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 WCF 构建的微型 Web 服务器

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.84/5 (11投票s)

2014年5月6日

Apache

8分钟阅读

viewsIcon

25426

downloadIcon

1108

使用 Windows Communication Foundation 构建一个简单的 Web 服务器

引言

本项目允许您创建和维护一个低使用率的服务器,而无需 Apache 或 IIS 的开销。

背景

我被委派的任务是提供一个通信服务器,该服务器将向客户端发送关于服务器上事件的通知。该任务的一部分是允许通过网站配置通信服务器。此服务有一个限制,即我们不允许安装除我们软件以外的任何其他东西,这意味着我们不能使用 IIS 作为主机。我将服务器作为自托管的 NT 服务编写完成,并在同一主机中编写了一个概念验证网站,可以提供一个 HTML 页面以及该页面上的一个图像。项目停滞了,概念验证也随之搁浅。

这是我努力将该概念验证变为现实,并展示 WCF 可用于实现低使用率的管理网站。

要求

本项目使用 Visual Studio 2013 和 .NET 4.5 构建,但我还包含了 VS2010 和 VS2012 的解决方案,它们都使用 .NET 4.0。据我所知,VS2008 不支持 .NET 4.0,所以我没有为此创建解决方案,也不打算创建。

您必须以管理员身份运行 DBWebHost.exe。解释如下。您还需要打开防火墙上的相应端口,以便其他客户端可以访问您的网站。

组件

该项目包含五个组件

  • DBWebHost.exe
  • HttpAccess.dll
  • DBServerLibrary.dll
  • DBWebsite.dll
  • DBTestsite.dll

DBWebHost 是主程序。它负责创建 WebServiceHost、打开它、关闭它以及进行清理。我使用的是 WebServiceHost 而不是 ServiceHost,因为它在编程上更容易设置,并且不需要显式配置行为。

要启用对服务的 HTTP 访问,您必须打开要在防火墙上使用的端口,并且需要配置 HTTP.SYS 以允许访问。大多数网站显示如何通过命令 shell 配置 HTTP.SYS,如下所示

netsh http add urlacl http://+:80/[service_name] user=[DOMAIN\user_name] sddl=[DACL] 

HttpAccess.dll 使用 HttpSetServiceConfiguration,它是 HttpApi 库的一部分。要使用此方法并指定 DACL,您需要以管理员身份运行它。我真的不推荐这种方法。更好的方法是在安装时进行设置,我以前这样做过。在这个项目中我没有这样做,因为我想展示 HttpSetServiceConfiguration 是如何工作的。如果您从安装程序或单独的进程调用 HttpAccess.dllDBWebHost.exe 就可以在没有管理员权限的情况下运行。

DBServerLibrary.dll 是路由器。IDBWebService 接口定义了路由结构以及服务接受的参数。DBWebService 实现了该接口。自上次发布以来,我已经对其进行了大量重写。该接口现在仅支持 Get Post 方法。有 Put Delete 的存根,但它们未激活,尽管我可能会在以后实现它们。

DBWebService 将接收传入的请求并将其解析为主机名、网站名、控制器名和操作名。操作名之后的任何内容都将作为查询字符串的一部分。然后,它将此信息以及传递的任何流与它们一起创建一个 Request 对象,然后可以将该请求对象传递给 Action 方法。

定义 Controller 类和 Action 方法有两种方式。

第一种方式是早期版本定义的方式:页面的 URI 由 /dbwebservice/{website}/{controller}/{action} 构建,其中 {website} 是您正在托管的网站模块的名称,{controller}Controller 类的名称前缀,{action} 是要调用的 Controller 上的方法名。这些值不区分大小写。DBWebService 将采用这些值,将其转换为小写,然后将第一个字母大写。例如,在路径 /dbwebservice/HOME/index 中,DBWebService 会将 "HOME" 转换为 "Home" 并附加 "Controller",因此预期的 Controller 名称是 "HomeController"。它会将 "index" 转换为 "Index",以便它可以在 "HomeController" 对象上查找 "Index" 方法。

第二种方式由 Controller 类和 Action 方法上的属性决定。我包含了一个 PathResolutionAttribute 类,可用于装饰 Controller 类和 Action 方法。DBServerLibrary.dll 中的一个辅助类 ParsedUri 将采用 {controller} 和 {action} 值,并在网站程序集中查找匹配项。如果它在程序集中找不到这些值,它将回退到查找 Controller 类和 Action 方法的旧方法。

现在,我应该提到 WebGet WebInvoke 属性上的 UriTemplate 属性已从 /{controller}/{action} 更改为 /{*path}。这允许请求 string 几乎可以是任何内容,因此服务器需要解析请求,而不是依赖于底层分派系统。

我包含了 IErrorController IResourceController 接口,它们是特殊情况的 Controller,用于显示错误和返回资源文件,例如图像、JavaScript、CSS 文件等。DBWebService 以前直接处理资源,但由于它现在可以处理多个网站,因此资源和错误请求现在应由网站本身处理。DBWebService 在无法解析请求字符串时查找这些接口,并首先尝试使用 IResourceController 解析,然后使用 IErrorController。如果请求 string 无法通过任一接口解析,则会创建一个默认的 ErrorController 对象并返回。

所有这些的一个额外好处是,您网站上使用的 HTML 链接现在可以是相对链接。早期版本不支持此功能。

DBWebsite.dll DBTestsite.dll 是渲染 HTML 并为网站提供资源(图像、脚本等)的网站实现,它们用于演示 Controllers Actions 的工作方式。它们演示了 CSS 如何应用,它们支持 JavaScript 和 JavaScript 库,如 jQuery、Ajax GET 和 Json POST,以及通过 PHP 进行 CGI 处理的支持。在此版本发布时,您不再局限于一个网站作为您的主机。

配置

可以在 App.config (实际上是 DBWebHost.exe.config) 中配置三个值

  • port 是要为请求打开的 port 的值。默认值为 80。它由 DBWebHost 使用。
  • secureport 是要为 SSL 请求打开的 port 的值。它由 DBWebHost 使用。
  • cert 是您用于 SSL 请求的证书的名称(主题)。它由 DBWebHost 使用。

有一个名为 ProcessorSection 的部分,其中包含有关不同 CGI 处理器信息。您不再局限于一种类型的处理器。它取代了 cgiExeccgiTypecgiParams

还有一个名为 SitesSection 的部分,其中包含您要包含的网站模块的名称及其路径。如果您在加载网站程序集时遇到问题,这是第一个需要查找的地方。它取代了模块配置值。

关注点

在 Visual Studio 中编辑 PHP 文件时要小心。PHP 不喜欢文件中的字节顺序标记 (BOM)。有关如何保存 PHP 处理器使用的文件,请参阅 PhpProcessor.cs

要测试 SSL,您需要购买一个证书,或者从您自己的证书颁发机构创建一个。我推荐阅读 Mike Meinz 的 如何成为自己的证书颁发机构并创建自己的证书来签名代码文件。服务器期望证书位于 LocalMachine 存储位置的 "My" 存储中。我将在未来的版本中使其可配置。

如果您在加载网站程序集时遇到任何问题,请首先检查 DBWebHost App.Config 文件,并确保 SitesSection 区域中的路径值正确。

查看发布说明以获取修复和新增功能。

有一个 TODO.txt 文件,其中概述了未来的改进。如果您有不在 TODO 列表中的功能请求,请告诉我。

包含的二进制文件是使用 VS2013 生成的。

历史

  • 版本 1.0:2014 年 5 月 5 日
    • 首次发布
  • 版本 1.0.2:2014 年 5 月 18 日
    • 增加了对 Visual Studio 2010 和 2012 的支持
    • 增加了对 Perl 处理的支持
    • 重构了 Session 集合,以便可以在工作线程上清理会话
    • 将 JQuery 方法更改为重载的 JavaScript 方法,以便可以使用任何库
    • 修复了各种 bug
  • 版本 1.0.3:2014 年 6 月 17 日
    • 增加了对 SSL 的支持
    • 增加了对自定义错误页的支持
    • 增加了对多个处理器引擎的支持
    • 增加了对多部分表单数据(用于上传文件)的支持
    • 增加了在 URI 错误时重定向到默认页面的支持
  • 版本 1.1.1:2014 年 7 月 6 日
    • 增加了对多个网站的支持
    • 简化了服务接口
    • 将资源请求推迟到网站
    • 允许 HTML 中链接和资源的相对路径
    • 允许通过属性定义 Controller 和 Action 名称
© . All rights reserved.