gpt4 book ai didi

c# - Asp.net Core Websocket 与 linux/docker 兼容吗?

转载 作者:太空宇宙 更新时间:2023-11-04 05:14:38 24 4
gpt4 key购买 nike

我使用 VS2017 创建了一个 Asp.net Core 2.1 项目,并配置了一个 Linux Docker 容器。

我想实现 websockets,所以我完全遵循了这个文档:https://learn.microsoft.com/en-us/aspnet/core/fundamentals/websockets?view=aspnetcore-2.1

如果我将 ASP.net 项目设置为启动项目(使用 IIS Express),则一切正常,并且我可以使用 chrome Smart Websocket Client 连接到 websocket 端点。扩展名。

但是,如果我将 Docker-compose 项目设置为启动项目(以便应用程序在 Linux 容器上运行),那么当我尝试连接到 websocket 端点时,我会在服务器上收到异常。

知道为什么这可以在 IIS Express 上运行,但不能在 Docker Linux 容器上运行吗?

这是一个异常(exception):

Failed to authenticate HTTPS connection.
System.IO.IOException: The handshake failed due to an unexpected packet format.
at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.PartialFrameCallback(AsyncProtocolRequest asyncRequest)
--- End of stack trace from previous location where exception was thrown ---
at System.Net.Security.SslState.ThrowIfExceptional()
at System.Net.Security.SslState.InternalEndProcessAuthentication(LazyAsyncResult lazyResult)
at System.Net.Security.SslState.EndProcessAuthentication(IAsyncResult result)
at System.Net.Security.SslStream.EndAuthenticateAsServer(IAsyncResult asyncResult)
at System.Net.Security.SslStream.<>c.<AuthenticateAsServerAsync>b__51_1(IAsyncResult iar)
at System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult iar, Func`2 endFunction, Action`1 endAction, Task`1 promise, Boolean requiresSynchronization)
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.AspNetCore.Server.Kestrel.Https.Internal.HttpsConnectionAdapter.InnerOnConnectionAsync(ConnectionAdapterContext context)
HttpsConnectionAdapter:Debug: Failed to authenticate HTTPS connection.

System.IO.IOException: The handshake failed due to an unexpected packet format.
at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.PartialFrameCallback(AsyncProtocolRequest asyncRequest)
--- End of stack trace from previous location where exception was thrown ---
at System.Net.Security.SslState.ThrowIfExceptional()
at System.Net.Security.SslState.InternalEndProcessAuthentication(LazyAsyncResult lazyResult)
at System.Net.Security.SslState.EndProcessAuthentication(IAsyncResult result)
at System.Net.Security.SslStream.EndAuthenticateAsServer(IAsyncResult asyncResult)
at System.Net.Security.SslStream.<>c.<AuthenticateAsServerAsync>b__51_1(IAsyncResult iar)
at System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult iar, Func`2 endFunction, Action`1 endAction, Task`1 promise, Boolean requiresSynchronization)
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.AspNetCore.Server.Kestrel.Https.Internal.HttpsConnectionAdapter.InnerOnConnectionAsync(ConnectionAdapterContext context)

更新1:

以下是有关如何创建项目的更多详细信息:

在 VS2017 中:

  • 文件 -> 新项目 -> ASP.NET Core Web 应用程序
  • 选择核心 2.1
  • 选择 API
  • 为 Linux 操作系统启用 Docker 支持
  • 点击“确定”

在Configure(...)的Startup.cs中我添加以下代码:

var webSocketOptions = new WebSocketOptions()
{
KeepAliveInterval = TimeSpan.FromSeconds(120),
ReceiveBufferSize = 4 * 1024
};
app.UseWebSockets(webSocketOptions);
app.Use(async (context, next) =>
{
if (context.Request.Path == "/ws")
{
if (context.WebSockets.IsWebSocketRequest)
{
WebSocket webSocket = await context.WebSockets.AcceptWebSocketAsync();
await Echo(context, webSocket);
}
else
{
context.Response.StatusCode = 400;
}
}
else
{
await next();
}

});

在 Startup.cs 中我添加以下函数

private async Task Echo(HttpContext context, WebSocket webSocket)
{
var buffer = new byte[1024 * 4];
WebSocketReceiveResult result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
while (!result.CloseStatus.HasValue)
{
await webSocket.SendAsync(new ArraySegment<byte>(buffer, 0, result.Count), result.MessageType, result.EndOfMessage, CancellationToken.None);

result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
}
await webSocket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None);
}
  • 当我启动应用程序 (iis express) 时,经典 API 使用 HTTP 运行,Websocket 也是如此。
  • 当我启动 docker 版本时,经典 API 使用 HTTP 运行,但不使用 Websocket(返回上述错误)。 -> 我必须调查的另一个错误。

我尝试在项目调试属性中激活 SSL:

  • 然后,当我启动应用程序 (iis express) 时,经典 API 正在使用 HTTPS 运行,但 Websocket 挂起(服务器端未收到任何信息)。
  • 当我启动 docker 版本时,经典 API 使用 HTTPS 运行,但不使用 Websocket(返回上述错误)。

最佳答案

好的,我刚刚发现发生了什么。

最初的问题是,即使项目未配置为使用 SSL(在“项目”->“属性”->“调试”->“启用 SSL”中),docker 容器仍将使用 HTTP。因此,您必须使用容器的 HTTPS 端口(可在 docker-compose.override.yml 中查看),并使用 wss://而不是 ws://

如果您尝试使用 HTTP 端口,则容器应用程序将尝试重定向到 HTTPS 端口。这就是发生在我身上的事情,导致了 HTTPS 错误。

关于我的开篇文章的“更多详细信息”部分,我没有使用 wss://而是 ws://,这就是 IIS Express 应用程序没有收到任何内容并且 Docker 应用程序仍然显示错误的原因。

关于c# - Asp.net Core Websocket 与 linux/docker 兼容吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50985533/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com