.NET 8在IIS 10部署MJPEG流API异常求助
.NET 8 API 部署到IIS 10后MJPEG视频流无法实时推送的问题解决
问题情况
基于.NET 8构建的API,后端连接IP摄像头拉取MJPEG流推送给浏览器,在Kestrel/Visual Studio环境下运行正常,但部署到IIS 10后出现异常:
- 客户端能连接服务器,但视频无法显示
- 浏览器开发者工具显示请求卡在「从服务器下载」状态
- 手动断开后端与IP摄像头的连接后,浏览器会快速显示几帧画面,请求随之完成
- 尝试过将摄像头流读入缓冲区再写入响应体,仅在Kestrel环境下有效,IIS环境仍无法正常工作
解决方案
一、调整IIS配置
禁用输出缓存
IIS默认会缓冲响应内容,导致MJPEG流无法实时推送。需针对/Video路径禁用缓存:- 打开IIS管理器,找到目标站点,双击「输出缓存」
- 点击「添加」,路径填
/Video,勾选「拒绝缓存」后确定
启用分块传输
MJPEG依赖分块传输才能实时推送,可通过web.config配置:<system.webServer> <httpProtocol> <customHeaders> <add name="Transfer-Encoding" value="chunked" /> </customHeaders> </httpProtocol> </system.webServer>延长请求超时时间
MJPEG是长连接,默认IIS超时时间过短会导致连接中断:- 站点→「高级设置」→「连接超时」,设置为3600秒(或更大值)
- 也可在web.config中配置:
<system.webServer> <aspNetCore requestTimeout="00:20:00" /> </system.webServer>
二、优化后端代码
直接返回摄像头流的方式在IIS下受缓冲机制影响,需手动逐块写入并强制刷新响应:
public async Task Video() { AppContext.SetSwitch("System.Net.Http.UseSocketsHttpHandler", false); string baseAddress = "http://192.168.1.100"; string clientId = "Username"; string clientSecret = "Password"; var credCache = new CredentialCache { { new Uri(baseAddress), "Digest", new NetworkCredential(clientId, clientSecret) } }; using HttpClient httpClient = new HttpClient(new HttpClientHandler { Credentials = credCache }); httpClient.BaseAddress = new Uri(baseAddress); using var cameraStream = await httpClient.GetStreamAsync("/cgi-bin/mjpg/video.cgi?channel=1&subtype=1"); HttpContext.Response.Headers.ContentType = "multipart/x-mixed-replace; boundary=--myboundary"; HttpContext.Response.Headers.TransferEncodingChunked = true; HttpContext.Response.BodyWriter.AutoFlush = true; byte[] buffer = new byte[4096]; int bytesRead; while ((bytesRead = await cameraStream.ReadAsync(buffer)) > 0) { await HttpContext.Response.Body.WriteAsync(buffer.AsMemory(0, bytesRead)); await HttpContext.Response.Body.FlushAsync(); // 强制刷新,确保数据实时发送 if (HttpContext.RequestAborted.IsCancellationRequested) break; // 客户端断开则终止循环 } }
三、验证ASP.NET Core模块
- 确保安装了对应.NET 8版本的ASP.NET Core Hosting Bundle,避免模块版本不兼容
- 可在web.config中开启日志排查问题:
<aspNetCore processPath="dotnet" arguments=".\YourApp.dll" stdoutLogEnabled="true" stdoutLogFile=".\logs\stdout" hostingModel="inprocess" />
内容的提问来源于stack exchange,提问作者Gdev27
相关产品推荐
相关产品推荐

