C# 可自定义嵌入式 HTTPServer






4.80/5 (10投票s)
一个可定制的 C# 嵌入式 HTTPServer。
引言
本文介绍了如何使用完全用 C# 编写的小型 HTTP 服务器库,该库可以集成到您自己的应用程序中使用。此库的目的是为开发人员提供一种简单易用且灵活的方式,根据请求的 URI 和/或应用程序的当前状态动态生成 HTTP 响应。
背景
该库由 Hybrid GeoTools 开发,用作集成 Web 服务器,为 Google Earth 提供动态数据。虽然乍一看处理 Google Earth 的请求是一项简单的任务,但事实证明,不正确地处理 HTTP 协议可能会导致意想不到的结果。例如,不正确地处理 Connect 标头会导致 Google Earth 重用连接,而服务器实际上正在等待新的连接。结果,请求根本没有被处理。
因此,开发了 HybridDSP.Net 库。目前,该库仅包含 HTTPServer
,但将来可能会添加更多服务。
设计
该库公开了四个类和两个接口
HTTPServer
- 这个类是实际的服务器。它管理连接、会话和请求。它将请求的处理委托给符合IHTTPRequestHandler
接口的请求处理程序对象。此对象是通过一个请求处理程序工厂获得的,该工厂作为 HTTPServer 的构造器的参数之一传递。此工厂必须符合IHTTPRequestHandlerFactory
接口。HTTPServerRequest
- 此类表示客户端到服务器的请求。请求处理程序工厂可以根据从请求获得的信息实例化请求处理程序。一旦请求处理程序被实例化,它将被用来处理请求。如果请求包含任何数据,可以从请求中获得一个Stream
来获取数据(并执行任何需要执行的操作)。HTTPServerResponse
- 此类表示从服务器到客户端的响应。默认情况下,它被初始化为返回 HTTP OK。正确设置所有标头后,可以通过将标头发送到客户端来获得一个Stream
。响应的主体可以写入到这个Stream
中。
IHTTPRequestHandler
- 此接口定义了任何请求处理程序需要遵守的契约。只定义了一个方法
public interface IHTTPRequestHandler
{
void HandleRequest(HTTPServerRequest request, HTTPServerResponse response);
}
IHTTPRequestHandlerFactory
- 此接口定义了任何请求处理程序工厂需要遵守的契约。同样,只定义了一个方法public interface IHTTPRequestHandlerFactory
{
IHTTPRequestHandler CreateRequestHandler(HTTPServerRequest request);
}
使用代码
首先,至少需要定义一个请求处理程序才能做任何事情。
class DateTimeHandler : IHTTPRequestHandler
{
public void HandleRequest(HTTPServerRequest request, HTTPServerResponse response)
{
if (request.URI == "/")
{
/**
* In this example we'll write the body into the
* stream obtained by response.Send(). This will cause the
* KeepAlive to be false since the size of the body is not
* known when the response header is sent.
**/
response.ContentType = "text/html";
using (Stream ostr = response.Send())
using (TextWriter tw = new StreamWriter(ostr))
{
tw.WriteLine("<html>");
tw.WriteLine("<head>");
tw.WriteLine("<title>Date Time Server</title>");
tw.WriteLine("<meta http-equiv=\"refresh\" content=\"2\">");
tw.WriteLine("</header>");
tw.WriteLine("<body>");
tw.WriteLine(DateTime.Now.ToString());
tw.WriteLine("</body>");
tw.WriteLine("</html>");
}
}
else
{
response.StatusAndReason = HTTPServerResponse.HTTPStatus.HTTP_NOT_FOUND;
response.Send();
}
}
}
这个处理程序将生成一个 HTML 页面,显示当前日期和时间,并每两秒钟刷新一次。如果请求不是针对根目录,它将返回一个 HTTP NOT FOUND 响应。
接下来,需要定义一个请求处理程序工厂才能使用刚创建的请求处理程序。
class RequestHandlerFactory : IHTTPRequestHandlerFactory
{
public IHTTPRequestHandler CreateRequestHandler(HTTPServerRequest request)
{
return new DateTimeHandler();
}
}
这个工厂将简单地始终实例化一个 DateTimeHandler。
最后一步是将所有东西连接在一起。为此,必须实例化一个工厂并将其传递给 HTTPServer 对象的构造器。然后,可以简单地启动服务器。
static void Main(string[] args)
{
RequestHandlerFactory factory = new RequestHandlerFactory();
HTTPServer server = new HTTPServer(factory, 8080);
server.Start();
Console.Write("Press enter to abort.");
Console.ReadKey();
server.Stop();
}
现在,打开你最喜欢的 Web 浏览器,浏览到 *https://:8080*,享受你自己的集成 Web 服务器。
历史
- 2007 年 9 月 12 日 - 首次发布。
- 2007 年 9 月 13 日 - 更新了截图。
- 2007 年 11 月 14 日 - 添加了对 IPv6 的支持。
- 2007 年 11 月 15 日 - 修复了终止服务器线程的问题。