.NET 嵌入式Web服务器 EmbedIO v3 入门详解
C# 嵌入式Web服务器 EmbedIO 入门教程
【张赐荣 / 译】
HTTP EmbedIO 介绍
EmbedIO 是一款适用于 C# 的轻量级、跨平台、模块化设计且采用 MIT 开源协议的 .NET Framework 与 .NET Core 嵌入式 Web 服务器。
- 完全使用 C# 编写,并依托我们精心打造的轻量级且功能强大的辅助库 SWAN
- 网络相关操作全面采用 async/await 异步模式:所有响应均以非阻塞方式处理
- 支持多种底层实现:EmbedIO 既可调用微软原生的
HttpListener,也可使用基于 Mono / websocket-sharp 项目自研的 HTTP 监听器 - 真正跨平台:已在多种操作系统与运行时环境中充分测试验证,从 Windows 上的 .NET Framework 到 Linux 上的 MONO 均可稳定运行
- 高度可扩展:您可自由开发自定义模块(如视频流媒体、UPnP 等),更多扩展模块请参阅 EmbedIO Extras
- 内存占用极低
- 借助开箱即用的 Web API 模块,可快速构建 RESTful 接口
- 仅需一行代码即可提供静态文件或嵌入式资源服务(同样开箱即用)
- 内置 LocalSessionWebModule,轻松实现会话管理
- 原生支持 WebSocket
- 完整支持 CORS,具备 Origin、Header、Method 校验及 OPTIONS 预检机制
- 支持 HTTP 206 断点续传(Partial Content)
- 支持 Xamarin Forms 应用集成
- 同一软件包内还包含更多实用功能
EmbedIO v3 全新特性
EmbedIO3.0 对 Web 服务器处理请求的流程及 Web 模块的管道机制进行了全面重构。v2 用户可查阅 升级指南 获取完整变更列表与迁移建议。
典型应用场景:
- 使用 React / AngularJS / Vue.js 或任意 JavaScript 框架,构建完全跨平台的图形界面应用
- 基于 Babylon.js 开发游戏,并让 EmbedIO 负责代码与资源的服务端分发
- 为 Windows 服务或 Linux 守护进程快速搭建管理界面
- 与 LiteLib 无缝集成,几分钟内即可为应用添加 SQLite 数据库支持
- 借助 WebSocket 实现客户端之间的实时通信
- 为 Xamarin Forms 应用内置轻量级 Web 服务器
集成说明
只需安装 NuGet 包,即可立即开始在您的 .NET 项目中使用 EmbedIO。
Package Manager
PM> Install-Package EmbedIO
.NET CLI
> dotnet add package EmbedIO
一些使用示例
EmbedIO 的上手门槛极低,参考以下入门教程即可快速开始使用。更多实用技巧与实现细节,请参阅 开发者手册(EmbedIO Cookbook)。
Web服务器基础配置
以下代码中的注释是关键说明,更多细节请参考示例项目。
namespace Unosquare
{
using System;
using EmbedIO;
using EmbedIO.WebApi;
class Program
{
/// <summary>
/// 应用程序入口点
/// </summary>
/// <param name="args">命令行参数</param>
static void Main(string[] args)
{
var url = "http://localhost:9696/";
if (args.Length > 0)
url = args[0];
// WebServer 实现了 IDisposable,建议使用 using 语句管理生命周期
using (var server = CreateWebServer(url))
{
// 注册模块并完成配置后,调用 RunAsync() 启动服务
server.RunAsync();
var browser = new System.Diagnostics.Process()
{
StartInfo = new System.Diagnostics.ProcessStartInfo(url) { UseShellExecute = true }
};
browser.Start();
// 等待用户按键后再释放 WebServer 资源
// 若用于系统服务场景,建议使用 BackgroundWorker 或 ManualResetEvent 等机制管理生命周期
Console.ReadKey(true);
}
}
// 创建并配置 WebServer 实例
private static WebServer CreateWebServer(string url)
{
var server = new WebServer(o => o
.WithUrlPrefix(url)
.WithMode(HttpListenerMode.EmbedIO))
// 依次注册所需模块
.WithLocalSessionManager()
.WithWebApi("/api", m => m
.WithController<PeopleController>())
.WithModule(new WebSocketChatModule("/chat"))
.WithModule(new WebSocketTerminalModule("/terminal"))
.WithStaticFolder("/", HtmlRootPath, true, m => m
.WithContentCaching(UseFileCache)) // 静态文件模块建议放在最后注册,避免路由冲突
.WithModule(new ActionModule("/", HttpVerbs.Any, ctx => ctx.SendDataAsync(new { Message = "Error" })));
// 监听服务器状态变更事件
server.StateChanged += (s, e) => $"WebServer 状态更新 - {e.NewState}".Info();
return server;
}
}
}
读取 POST 请求体:表单数据(application/x-www-form-urlencoded)
如要在 WebAPI 方法中读取表单格式的请求体,只需为方法参数添加 [FormData] 特性:
[Route(HttpVerbs.Post, "/data")]
public async Task PostData([FormData] NameValueCollection data)
{
// 对接收到的数据执行业务逻辑
await SaveData(data);
}
读取 POST 请求体:JSON 数据(application/json)
若要读取并反序列化 JSON 请求体,可使用 GetRequestDataAsync 方法。该方法直接扩展自 IHttpContext,并返回泛型指定的对象实例:
[Route(HttpVerbs.Post, "/data")]
public async Task PostJsonData()
{
var data = await HttpContext.GetRequestDataAsync<MyData>();
// 对接收到的数据执行业务逻辑
await SaveData(data);
}
读取 POST 请求体:FormData 多部分数据(multipart/form-data)
EmbedIO 本身没有内置 multipart/form-data 流解析功能,但您可借助 HttpMultipartParser NuGet 包 轻松实现。该库小巧实用,可直接将 Request.InputStream 传入解析器:
[Route(HttpVerbs.Post, "/upload")]
public async Task UploadFile()
{
var parser = await MultipartFormDataParser.ParseAsync(Request.InputStream);
// 现在可通过 parser.Files 访问上传的文件
}
也可以参考 另一种解决方法,但需额外引用 Microsoft.AspNet.WebApi.Client NuGet 包。
输出二进制流
您可通过扩展方法 OpenResponseStream 直接操作响应输出流:
[Route(HttpVerbs.Get, "/binary")]
public async Task GetBinary()
{
// 假设从外部源获取数据
using (var stream = HttpContext.OpenResponseStream())
await stream.WriteAsync(dataBuffer, 0, dataBuffer.Length);
}
WebSocket 使用示例
使用 WebSocket 非常简单:只需继承抽象类 WebSocketModule 并按下例注册模块:
server.WithModule(new WebSocketChatModule("/chat"));
对应的 WebSocket 服务端实现示例如下:
namespace Unosquare
{
using EmbedIO.WebSockets;
/// <summary>
/// 简易聊天室 WebSocket 服务端实现
/// </summary>
public class WebSocketsChatServer : WebSocketModule
{
public WebSocketsChatServer(string urlPath)
: base(urlPath, true)
{
// 初始化逻辑(可按需扩展)
}
/// <inheritdoc />
protected override Task OnMessageReceivedAsync(
IWebSocketContext context,
byte[] rxBuffer,
IWebSocketReceiveResult rxResult)
=> SendToOthersAsync(context, Encoding.GetString(rxBuffer));
/// <inheritdoc />
protected override Task OnClientConnectedAsync(IWebSocketContext context)
=> Task.WhenAll(
SendAsync(context, "欢迎加入聊天室!"),
SendToOthersAsync(context, "有新用户加入聊天室。"));
/// <inheritdoc />
protected override Task OnClientDisconnectedAsync(IWebSocketContext context)
=> SendToOthersAsync(context, "有用户离开了聊天室。");
private Task SendToOthersAsync(IWebSocketContext context, string payload)
=> BroadcastAsync(payload, c => c != context);
}
}
SSL 支持
EmbedIO 的两种 HTTP 监听器实现(微软原生版与 Unosquare 自研版)均支持通过 SSL 启动 Web 服务。目前该功能仅支持 Windows 平台,您需手动注册证书,或通过 WebServerOptions 类初始化 WebServer 实例时自动完成证书绑定。本节将提供 SSL 配置示例,并简要说明 Windows 平台下 SSL 的工作机制。
对于 Windows Vista 及更高版本,微软提供了网络配置命令行工具 netsh。该工具可将 IP:端口 与证书进行映射,使传入的 HTTP 请求能基于指定证书升级为 HTTPS 安全连接。EmbedIO 支持读取或向默认证书存储区(My/LocalMachine)注册证书,并自动使用证书指纹通过 netsh sslcert 命令为第一个注册的 https 前缀完成绑定。
对于 Windows XP 或 Mono 环境,您可手动使用 httpcfg 工具完成证书绑定配置。
使用 PFX 文件 + AutoRegister 自动注册
最便捷的 SSL 集成方式是启用 AutoRegister 选项。您只需创建 WebServerOptions 实例,指定 PFX 证书文件路径并开启 AutoRegister 标志。系统将尝试从默认证书存储区获取或自动注册该证书,随后使用证书指纹通过 netsh 为配置中首个 https 前缀完成绑定。
使用 AutoLoad 自动加载
若您已在默认证书存储区中安装证书,且 netsh 中已完成对应绑定,可启用 AutoLoad 标志(可选提供证书指纹)。若未显式指定指纹,EmbedIO 将自动从 netsh 配置中读取。成功获取证书后,其原始数据将直接传递给 WebServer 实例使用。
相关项目与 NuGet 包
| 名称 | 作者 | 描述 |
|---|---|---|
| Butterfly.EmbedIO | Fireshark Studios, LLC | 基于 EmbedIO 服务器实现的 Butterfly.Core.Channel 与 Butterfly.Core.WebApi 集成方案 |
| embedio-cli | Unosquare | .NET 全局工具,支持通过命令行快速启动任意 Web 目录或 EmbedIO 程序集(WebAPI / WebSocket) |
| EmbedIO.BearerToken | Unosquare | 支持 Bearer Token 身份验证。提供 /token 端点,通过自定义验证委托生成 JsonWebToken;可配置为校验全部请求或指定路径 |
| EmbedIO.LiteLibWebApi | Unosquare | 结合 EmbedIO WebApi 与 LiteLib,快速将 SQLite 数据库暴露为 RESTful API |
| EmbedIO.OWIN | Unosquare | EmbedIO 与 OWIN 平台的双向集成:既可将 EmbedIO 作为 OWIN 服务器运行,也可在 EmbedIO 模块中复用 OWIN 生态组件 |
| Microsoft.AspNetCore.Server.EmbedIO | Dju | 为 ASP.NET Core 提供 EmbedIO 后端支持,可作为 Kestrel 的无缝替代方案 |
| SambaFetcher | nddipiazza | .NET 工具,实现 Web 服务器与 Samba 文件共享服务的对接 |
| SimpleW | stratdev3 | 受 EmbedIO 启发设计的 .NET Core Web 服务器库 |
| LiquidPages | Kinetq | 通用 Liquid 模板渲染中间件,支持任意 Web 服务器,内置 EmbedIO 适配 |
特别鸣谢
感谢 YourKit 为开源项目提供功能强大的 .NET Profiler —— 一款出色的 CPU 与内存性能分析工具!
译者:
张赐荣,视障者,信息无障碍软件优化解决方案研发专家。
从事Web/PC/移动端无障碍解决方案研究工作多年,对跨平台可访问性优化实践拥有独特的理论和丰富的实战经验。
精通视障用户体验交互设计,致力于改善、提升产品可及性和易用性。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)