如何在docker镜像中运行signalr blazor客户端的StartAsync连接?

bat*_*yar 3 signalr docker asp.net-core blazor

我创建了默认的 blazor 服务器端应用程序。然后添加Microsoft.AspNetCore.SignalR.ClientChatHub类。然后编辑startup.cs文件(添加services.AddSignalR()endpoints.MapHub<ChatHub>("/chatHub"))和index.razor页面。然后通过IIS Express运行。没关系。

然后添加docker支持并运行Docker主机。它不工作。因为只有集线器连接 StartAsync 方法不起作用。如何运行它?帮我?非常感谢你们。

错误是:

处理请求时发生未处理的异常。SocketException:无法分配请求的地址System.Net.Http.ConnectHelper.ConnectAsync(字符串主机,int端口,CancellationToken取消令牌)

HttpRequestException:无法分配请求的地址System.Net.Http.ConnectHelper.ConnectAsync(字符串主机,int端口,CancellationToken取消令牌)

索引.剃刀代码:

@code {
    private HubConnection _hubConnection;

    protected override async Task OnInitializedAsync()
    {
        _hubConnection = new HubConnectionBuilder()
            .WithUrl(NavigationManager.ToAbsoluteUri("/chatHub"))
            .Build();

        _hubConnection.On<string, string>("ReceiveMessage", (user, message) =>
        {
            var encodedMsg = $"{user}: {message}";
            StateHasChanged();
        });

        await _hubConnection.StartAsync(); // **DON'T WORK IN DOCKER HOST.**
    }
}
Run Code Online (Sandbox Code Playgroud)

Docker 文件:

FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base
WORKDIR /app
EXPOSE 80

FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build
WORKDIR /src
COPY ["BlazorApp1/BlazorApp1.csproj", "BlazorApp1/"]
RUN dotnet restore "BlazorApp1/BlazorApp1.csproj"
COPY . .
WORKDIR "/src/BlazorApp1"
RUN dotnet build "BlazorApp1.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "BlazorApp1.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "BlazorApp1.dll"]
Run Code Online (Sandbox Code Playgroud)

itm*_*nus 6

我最好的猜测是您的集线器客户端正在尝试连接到“the-public-url-out-of-docker/chatHub”:

\n\n
\n
    _hubConnection = new HubConnectionBuilder()\n        .WithUrl(NavigationManager.ToAbsoluteUri("/chatHub"))\n        .Build();\n
Run Code Online (Sandbox Code Playgroud)\n
\n\n

NavigationManager.ToAbsoluteUri(...)将转换/chatHub为向最终用户公开的公共 URL。例如,如果您使用反向代理,则它可能是域名。

\n\n

请注意,存在三个不同级别的 url:

\n\n
    \n
  • 向公众公开的域名
  • \n
  • 主机ip和端口
  • \n
  • 容器ip和端口
  • \n
\n\n
  +----------------------------------+\n  | HOST  (5000)                     |\n  |   +                              |\n  |   |Port Mapping---------------+  |\n  |   >-->-->|Container (80)      |  |\n  |          |                    |  |\n  |          +--------------------+  |\n  +-----^----------------------------+\n        |  reverse proxy\n+-------+----------------------------+\n| nginx                              |\n|  https://www.myexample.com/chatHub\n|                                    |\n+-------^----------------------------+\n        |\n        |\n        |\n        |\n+-------+-----------+\n|                   |\n|   Browser         | (Brazor sees only the public url via NavgiationManager  )\n|                   |\n+-------------------+\n
Run Code Online (Sandbox Code Playgroud)\n\n

然而,当在docker中运行时,主机的网络始终无法从容器的网络访问。

\n\n

如果是这种情况,有几种方法应该有效\xef\xbc\x9a

\n\n
    \n
  1. 避免使用公共网址,例如.WithUrl(NavigationManager.ToAbsoluteUri("/chatHub")). 将其硬编码到容器 IP 和端口。例如,如果您的容器侦听 80,则它应该是http://localhost/chatHub.
  2. \n
  3. 为docker配置网络,或者--network在运行docker时添加一个for。有关更多详细信息,请参阅此线程
  4. \n
\n