You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET Core中HTTPS下静态文件与WebSocket共存问题排查

ASP.NET Core单服务器同时提供HTTPS静态文件与WebSocket连接的405错误问题

问题背景

使用C#的WebApplication搭建ASP.NET Core服务器,需求是同时提供静态文件服务与HTTPS协议的WebSocket连接。HTTP环境下使用ws://连接完全正常,页面加载、WebSocket通信、重连均无问题,但切换为HTTPS(wss://与https://)后出现异常。

基础测试代码

var builder = WebApplication.CreateBuilder();

builder.Services.Configure<KestrelServerOptions>(options =>
{
    var cert = new X509Certificate2("cert.pfx", "password");

    options.Listen(IPAddress.Any, 80);
    options.Listen(IPAddress.Any, 443, listenOptions =>
    {
        listenOptions.UseHttps(cert);
    });
});


var app = builder.Build();

app.UseWebSockets();
app.MapGet("/ws", HandleWebSocket);

app.UseDefaultFiles();
app.UseStaticFiles();

app.RunAsync();

WebSocket处理方法仅实现消息回显逻辑,静态文件包含简单HTML页面与图片,页面脚本会循环尝试建立WebSocket连接并发送消息。

错误现象

HTTPS环境下首次启动服务器并加载页面时,静态文件可正常获取,但WebSocket连接触发服务器405错误,日志如下:

info: Microsoft.AspNetCore.Routing.EndpointMiddleware[0]
      Executing endpoint '405 HTTP Method Not Supported'
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[1]
      Executed endpoint '405 HTTP Method Not Supported'
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
      Request finished HTTP/2 CONNECT https://127.0.0.1/ws - 405 0 - 2.7369ms
info: Microsoft.AspNetCore.Server.Kestrel[32]
      Connection id "0HN410OGAJS3S", Request id "0HN410OGAJS3S:00000005": the application completed without reading the entire request body.

WebSocket处理方法从未被调用。但保持脚本运行并重启服务器后,WebSocket即可正常连接。

当前临时方案与疑问

目前采用两个不同端口的WebApplication分别处理静态文件与WebSocket的方案可正常运行,但怀疑HTTPS下浏览器加载静态文件的长连接无法升级为WebSocket连接。需确认:

  • 该猜测是否正确
  • 当前配置是否存在问题
  • 是否必须使用双服务器,或能否通过单服务器实现需求

补充WebSocket处理方法代码

private static async Task HandleWebSocket(HttpContext context)
{
    if (!context.WebSockets.IsWebSocketRequest)
    {
        context.Response.StatusCode = StatusCodes.Status400BadRequest;
        await context.Response.WriteAsync("Expected a WebSocket request");
        return;
    }

    var socket = await context.WebSockets.AcceptWebSocketAsync();

    var buffer = new byte[1024];
    var result = await socket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);

    while (socket.State == WebSocketState.Open)
    {
        var data = Encoding.UTF8.GetString(buffer, 0, result.Count);
        Console.WriteLine("Received: " + data);

        var response = Encoding.UTF8.GetBytes("Echo - " + data);
        await socket.SendAsync(new ArraySegment<byte>(response), result.MessageType, result.EndOfMessage, CancellationToken.None);

        result = await socket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
    }

    await socket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None);
}

内容的提问来源于stack exchange,提问作者Mars

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 03:14:52