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

时间:2020-02-26 07:04:16

标签: docker asp.net-core signalr 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端口,CancelationToken cancelToken)

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

index.razor代码:

@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.**
    }
}

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"]

1 个答案:

答案 0 :(得分:2)

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

    _hubConnection = new HubConnectionBuilder()
        .WithUrl(NavigationManager.ToAbsoluteUri("/chatHub"))
        .Build();

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

请注意,网址分为三个不同的级别:

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

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

如果是这样,有几种方法应该可行:

  1. 避免使用.WithUrl(NavigationManager.ToAbsoluteUri("/chatHub"))之类的公共网址。将其硬编码到容器ip&port。例如,如果您的容器监听80,则应为http://localhost/chatHub
  2. 为docker配置网络,或在运行docker时添加--network。有关更多详细信息,请参见this thread