我觉得我在这次代码短途旅行中遗漏了一些东西。让我带您了解一下。
在 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);
我知道代码有效。当我在 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"]
然后我用 Docker-compose.yml 提取所有内容:
version: '3'
services:
xevenlistens:
image: danregalia/xevenlistens:latest
network_mode: "host"
container_name: x7Listens
ports:
- "8001:8001"
所以,按照我的逻辑……当我在 VSCode 中编写它,并且它显示在 docker 桌面中时,我得到了预期的应用程序。我检查了它,我看到了这个:
当我转到终端选项卡时,对 localhost:8001 运行 curl 我得到了正确的响应,所以我知道这是有效的:
现在我知道我的映射是正确的。从 docker 文件和上面的图片中,您可以看出我已经按应有的方式映射了端口 8001,并且从 dockerfile 中我已经暴露了 8001。
在这一点上,我有足够的信心,如果我从我的浏览器运行 http://localhost:8001,我应该返回同样简单的 html 消息......对吗?
错...
所以,现在我完全不知道为什么这不起作用。我现在唯一能想到的是,我的 wsl 不在 localhost 或 127.0.0.1 或 192.168.0.22(我电脑上的 eth0 ipv4)
欢迎任何人提出任何想法..但我已经通过我能想到的最好的方式追踪了这一点,通读了其他 6 篇类似的帖子。
大家干杯。 (编辑以清理第一段中我破碎的想法..)
问题在这里 -
public static string url = "http://localhost:8001/";
它将只接受来自本地主机的请求,对于 dockerized 应用程序,它将是容器本身。将 localhost
更改为 +
:
public static string url = "http://+:8001/";
HttpListener
文档:
指定端口时,主机元素可以替换为“”,表示如果请求的 URI 不匹配任何其他前缀,则 HttpListener 接受发送到该端口的请求。例如,当请求的 URI 未被任何 HttpListener 处理时,要接收发送到端口 8080 的所有请求,前缀为 http://:8080/。同样,要指定 HttpListener 接受发送到端口的所有请求,请将主机元素替换为“+”字符。例如,https://+:8080。 “*”和“+”字符可以出现在包含路径的前缀中。