C# .NET Core 7 Http Listener 应用程序,包装在 docker 中,无法从 localhost 访问

Dre*_*lia 4 c# httplistener docker .net-core docker-compose

我觉得我在这次代码短途旅行中遗漏了一些东西。让我引导您完成这个过程。

在 C# 中,我使用非常简单的代码。没有launchsettings.json,只需对其进行硬编码以查看是否有效。以下是设置和主要内容,以便您可以看到它是如何启动的:

public class Program
{
    public static HttpListener listener;
    public static string url = "http://localhost:8001/";
---- later on in main:------
public static void Main(string[] args)
    {
        listener = new HttpListener();
        listener.Prefixes.Add(url);
        listener.Start();
        Console.WriteLine("Listening for connections on {0}", url);
Run Code Online (Sandbox Code Playgroud)

我知道该代码有效。当我在 VS2022 调试模式(无 docker)下运行时,它显示我的简单 html 页面,上面写着“系统正常”。如果我在 docker 中运行它,这就是一切变得奇怪的地方。我现在将介绍 docker 配置。

Docker文件:

FROM mcr.microsoft.com/dotnet/runtime:7.0 AS base
WORKDIR /app

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

FROM build AS publish
RUN dotnet publish "xevenListens.csproj" -c Release -o /app/publish /p:UseAppHost=false

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

然后我用以下命令拉出所有内容Docker-compose.yml

version: '3'
services:
  xevenlistens:
    image: danregalia/xevenlistens:latest
    network_mode: "host"
    container_name: x7Listens
    ports:
      - "8001:8001"
Run Code Online (Sandbox Code Playgroud)

因此,按照我的逻辑,当我在 VSCode 中编写它并显示在 docker 桌面中时,我会按预期获得应用程序。我检查了一下,看到了这个: 显示 Docker 桌面检查的图像

当我转到“终端”选项卡时,运行curllocalhost:8001我得到了正确的响应”,所以我知道它正在工作: 本地主机的卷曲结果

现在我知道我的映射是正确的。从 docker 文件和上面的图片中,您可以看出我已经按照应有的方式映射了端口 8001,并且从我dockerfile已经暴露了 8001。

此时,我有足够的信心,如果我从浏览器运行 http://localhost:8001,我应该返回相同的简单 html 消息...对吧?
错误的...

本地主机没有向我显示任何内容

所以,现在我完全不知道为什么这不起作用。我现在唯一能想到的是,我的 wsl 不在 localhost 或 127.0.0.1 或 192.168.0.22 上(我的计算机上的 eth0 ipv4)

我已经通过我能想到的最好的方式追踪了这一点,并阅读了其他 6 篇类似的帖子。

Gur*_*ron 6

问题就在这里 -public static string url = "http://localhost:8001/";它只会接受来自本地主机的请求,对于 Docker 化应用程序来说,该请求将是容器本身。更改 localhost+(或*):

public static string url = "http://+:8001/";
Run Code Online (Sandbox Code Playgroud)

来自HttpListener文档

指定端口后,可以将主机元素替换为,*以指示HttpListener如果请求的 URI 与任何其他前缀都不匹配,则接受发送到该端口的请求。例如,要在请求的 URI 未由任何 处理时接收发送到端口 8080 的所有请求HttpListener,前缀为http://*:8080/。同样,要指定HttpListener接受发送到端口的所有请求,请将 host 元素替换为该+字符。例如,https://+:8080。和字符可以出现在包含路径的前缀中*+