Skip to main content
 首页 » 编程设计

c#之无法连接到 Docker 容器中托管的 WCF 服务

2024年01月13日42arxive

我正在尝试运行一个在 Docker 容器中公开 WCF 服务的应用程序。

该应用程序是使用 TopShelf 构建的,因此它既可以作为 Windows 服务运行,也可以(在开发中)作为独立的控制台程序运行。

我遇到的问题是 WCF 测试客户端无法获取元数据。值得一提的是,该应用程序在本地执行时可以正常工作。

这是应用程序在本地运行时 WCF 测试客户端生成的元数据文件

<?xml version="1.0" encoding="utf-8"?> 
<configuration> 
    <system.serviceModel> 
        <bindings> 
            <netTcpBinding> 
                <binding name="NetTcpBinding_ITestWcfDocker" sendTimeout="00:05:00"> 
                    <security mode="None" /> 
                </binding> 
            </netTcpBinding> 
        </bindings> 
        <client> 
            <endpoint address="net.tcp://localhost:9998/" binding="netTcpBinding" 
                bindingConfiguration="NetTcpBinding_ITestWcfDocker" contract="ITestWcfDocker" 
                name="NetTcpBinding_ITestWcfDocker" /> 
        </client> 
    </system.serviceModel> 
</configuration> 

这是我用来构建容器的 Dockerfile

FROM microsoft/dotnet-framework:4.6.2 
RUN powershell -Command Add-WindowsFeature NET-WCF-HTTP-Activation45 
WORKDIR app 
COPY bin/Release/net461 . 
EXPOSE 9998 9999 
ENTRYPOINT ["EMG.Service.TestWcfDocker.exe"] 

构建项目后,我使用此命令构建容器

docker build -t emg/test-wcf:latest . 

然后我用这个命令启动一个容器

docker run -p 9998:9998 -p 9999:9999 -t emg/test-wcf 

这是我在控制台日志中得到的输出

Configuration Result: 
[Success] Name EMG.TestWcfDocker, [Success] DisplayName EMG TestWcfDocker, [Success] Description EMG TestWcfDocker, [Success] ServiceName EMG.TestWcfDocker 
Topshelf v4.0.0.0, .NET Framework v4.0.30319.42000 
2017-05-15 15:46:48.0700|DEBUG|WcfServiceHost|Adding NetTcpBinding endpoint for ITestWcfDocker at net.tcp://localhost:9998/ 
2017-05-15 15:46:48.1012|DEBUG|WcfServiceHost|Adding Metadata endpoint at http://localhost:9999/ 
2017-05-15 15:46:49.2207|INFO|EMG.TestWcfDocker.Program|Starting EMG.TestWcfDocker 
The EMG.TestWcfDocker service is now running, press Control+C to exit. 
2017-05-15 15:46:50.2675|INFO|EMG.TestWcfDocker.Program|EMG.TestWcfDocker started 

容器启动后,我用它来获取容器的IP

docker inspect -f="{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}" container-name 

然后我使用返回的 IP 通过 WCF 测试客户端连接到服务,但我收到此错误消息

Error: Cannot obtain Metadata from http://172.19.111.72:9999/ If this is a Windows (R) Communication Foundation service to which you have access, please check that you have enabled metadata publishing at the specified address.  For help enabling metadata publishing, please refer to the MSDN documentation at http://go.microsoft.com/fwlink/?LinkId=65455.WS-Metadata Exchange Error    URI: http://172.19.111.72:9999/    Metadata contains a reference that cannot be resolved: 'http://172.19.111.72:9999/'.    There was no endpoint listening at http://172.19.111.72:9999/ that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details.    Unable to connect to the remote server    A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond 172.19.111.72:9999HTTP GET Error    URI: http://172.19.111.72:9999/    There was an error downloading 'http://172.19.111.72:9999/'.    Unable to connect to the remote server    A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond 172.19.111.72:9999 

如果我使用本地主机,我会遇到类似的错误。

tl;博士:

我在 Docker 容器中有一个 WCF 服务,我无法从主机连接到它。

请您参考如下方法:

因此您需要为 TCP 托管支持执行此操作:

SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"] 

安装托管在 IIS 上的 WCF 服务所需的 Windows 组件

RUN Add-WindowsFeature NET-WCF-TCP-Activation45; \ 
Add-WindowsFeature NET-WCF-HTTP-Activation45; \ 
Add-WindowsFeature Web-WebSockets 

在 IIS 上为默认网站启用 net.tcp 协议(protocol)

RUN windows\system32\inetsrv\appcmd.exe set app 'Default Web Site/' /enabledProtocols:"http,net.tcp" 
 
EXPOSE 808