在Web应用程序中设置WCF TCP服务

Nie*_*nch 29 c# wcf wcf-binding net.tcp

我已经和它斗争了好几天,实际上经历了一百篇文章,给出了如何在Web应用程序中设置基于WCF TCP的服务的部分指导.如果有人可以帮助我,我会将这个问题变成一个完整的指南.

当前状态

net.tcp连接适用于我的开发机器.它在部署到Windows Server 2008 R2后也可在本地运行.但是,它不能远程工作,即使可以远程telnet到服务器上的端口808.滚动到问题的底部以获取详细信息.如果可以的话请帮忙.

我将为此详细信息创建一个新问题,如果我从中得到结果,则用答案更新此问题.

我创建ServerHubService.svc了以下内容:

namespace Manage.SignalR
{
    [ServiceContract]
    public class ServerHubService
    {
        [OperationContract]
        public void UpdateServerStatus(string serverStatus)
        {
            // Do something
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

托管服务的应用程序的配置

在线教程之后,我在Web.config中添加了以下内容(我尝试了很多不同的变体).这是托管该服务的Web应用程序的Web.config,后来我想用TCP连接.

<configuration>
  <system.serviceModel>
    <services>
      <service behaviorConfiguration="ServerHubBehavior"
      name="Manage.SignalR.ServerHubService">
        <endpoint address=""
              binding="netTcpBinding"
              bindingConfiguration="portSharingBinding"
              name="MyServiceEndpoint"
              contract="Manage.SignalR.ServerHubService">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>

        <endpoint address="mex"
              binding="mexTcpBinding"
              bindingConfiguration=""
              name="MyServiceMexTcpBidingEndpoint"
              contract="IMetadataExchange" />
        <host>
          <baseAddresses>
            <add baseAddress="net.tcp://test.mydomain.com:808/SignalR/ServerHubService.svc" />
          </baseAddresses>
        </host>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="ServerHubBehavior">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="false" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <bindings>
      <netTcpBinding>
        <binding name="portSharingBinding" portSharingEnabled="true"/>
      </netTcpBinding>
    </bindings>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true"
      minFreeMemoryPercentageToActivateService="0" multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
</configuration>
Run Code Online (Sandbox Code Playgroud)

httpGetEnabled="true" 很重要,否则您无法创建服务的服务引用.

配置运行Web应用程序的服务器

我在我的具有IIS 7.5的开发机器上进行设置

我读到IIS Express(内置于Visual Studio中)不支持net.tcp,因此我使用.NET 4.5在IIS 7.5中设置了一个新网站并且具有net.tcp绑定

IIS中的绑定

我还进入了网站的高级设置并将启用协议设置为 http,net.tcp

我确保启用(并重新启动)Windows功能非HTTP激活.这是一个Windows功能,所以寻找"打开或关闭Windows功能"来找到它.

在此输入图像描述

确认Web应用程序正在运行

该网站适用于其余的Web应用程序.我在我的hosts文件中设置test.mydomain.com指向127.0.0.1 .我甚至可以访问http://test.mydomain.com/SignalR/ServerHubService.svc,它将向我展示一个很好的自动生成的.NET页面,解释如何使用此服务.

到现在为止还挺好.

.NET生成的页面告诉我使用此地址生成与我的服务的连接:

net.tcp://computername/SignalR/ServerHubService.svc/mex
Run Code Online (Sandbox Code Playgroud)

尝试以客户端身份连接到服务

如果您不记得设置httpGetEnabled="true",则在尝试创建服务引用时会出现错误.如果您使用WCF测试客户端(也是Visual Studio中包含的工具)并且未设置httpGetEnabled,则会出现如下错误:

错误:无法从net.tcp获取元数据://computername/SignalR/ServerHubService.svc/mex

如果这是您有权访问的Windows(R)Communication Foundation服务,请检查您是否已在指定地址启用元数据发布.有关启用元数据发布的帮助,请参阅MSDN文档,网址http://go.microsoft.com/fwlink/?LinkId=65455.WS-Metadata

Exchange错误URI:的net.tcp://computername/SignalR/ServerHubService.svc/mex元数据包含无法解析的引用: '的net.tcp://computername/SignalR/ServerHubService.svc/mex'.无法连接到net.tcp://computername/SignalR/ServerHubService.svc/mex.连接尝试持续时间跨度为00:00:04.0032289.

TCP错误代码10061:无连接可以作出,因为目标机器积极拒绝,[2001:0:4137:9e76:C81:A4C:A547:b2fd]:808.没有连接,因为目标机器主动拒绝它[2001:0:4137:9e76:c81:a4c:a547:b2fd]:808

但是,如果您已完成上述所有操作,则应该能够添加对服务的引用.

在服务中调用方法

尝试从WCF测试客户端调用服务中的简单Hello World方法时,它返回以下错误:

无法连接到net.tcp://computername/SignalR/ServerHubService.svc.连接尝试持续时间跨度为00:00:04.0002288.TCP错误代码10061:无法建立连接,因为目标计算机主动拒绝它.

这是包含在错误中的内部堆栈跟踪:

在系统808 System.Net.Sockets.Socket.DoConnect(端点endPointSnapshot,为SocketAddress的SocketAddress):无连接可以作出,因为目标机器积极拒绝,[2001:0:5ef5:石川铃华:3884:A:A547:b2fd] .Net.Sockets.Socket.Connect(端点remoteEP)在System.ServiceModel.Channels.SocketConnectionInitiator.Connect(URI的URI,时间跨度超时)

如果您使用netstat -an |find /i "listening"以查看端口808上没有任何内容正在侦听,则可能是因为Net.Tcp侦听器适配器服务未运行.

确认

这个电话现在已经过去,但在宣布成功之前需要一些确认.我需要确认这实际上是端口808上的net.tcp调用,而不是http端点上的实际调用.我试图用Wireshark做这个,但它没有出现,可能是因为它是从本地机器发出的呼叫.

部署

征服的最后一个挑战是将其部署在Web服务器上,确保在开发机器上运行的是什么,也可以在Web服务器上运行.

发布到Windows Server 2008 R2后,它不起作用.它给出了共同点SocketException: An existing connection was forcibly closed by the remote host.

它在服务器上本地运行良好,但它不能远程工作.

以下是用于检查服务器的清单:

  • Net.Tcp Listener Adapter服务运行?是
  • 是否将IIS站点绑定net.tcp设置为808:*?是
  • IIS中的站点的高级设置下的启用协议是否设置为http,net.tcp?是
  • 服务器是否在端口808上侦听?是的,选中netstat -an |find /i "listening"
  • 防火墙是否打开808端口?是.
    • 防火墙在服务器上关闭.
    • 我可以从外面通过端口808 telnet到服务器 telnet mydomain.com 808
  • 在服务器上的服务配置中,确认了以下内容:
    • baseAddress调整为 net.tcp://mydomain.com:808/SignalR/ServerHubService.svc
    • 这是localhost之前的,但mydomain.com在服务器上无法运行后更改为:<identity><dns value="mydomain.com" /></identity>
  • 它已在服务器和另一台服务器上本地客户端进行了测试.两者都可以使用telnet连接到端口808,并且都提供相同的错误消息.

服务器上可能缺少哪些配置?我非常接近目标.请协助我解决此问题并完成问题.

以下是调用服务的服务器上的客户端配置:

<system.serviceModel>
  <bindings>
    <netTcpBinding>
      <binding name="MyServiceEndpoint" />
    </netTcpBinding>
  </bindings>
  <client>
    <endpoint address="net.tcp://mydomain.com:808/SignalR/ServerHubService.svc"
      binding="netTcpBinding" bindingConfiguration="MyServiceEndpoint"
      contract="ServerHubService.ServerHubService" name="MyServiceEndpoint">
      <identity>
        <dns value="mydomain.com" />
      </identity>
    </endpoint>
  </client>
</system.serviceModel>
Run Code Online (Sandbox Code Playgroud)

我也尝试在端点中没有配置808,因为据传这是net.tcp连接的默认端口.但是,它仍然给出了相同的结果.

而不是随意尝试很多东西,好的问题可能是:如何调试这样的东西?我可以在任一服务器上安装一个程序,它会告诉我为什么这个电话被阻止了?

通过这样配置的Wireshark,可以查看端口808上到达服务器的呼叫,并可能确定呼叫无效的原因.但是,我不知道目前如何分析这个问题.

Wireshark的

祝好运

我放弃了并在套接字层实现了这一点.它立即起作用.不过,我希望这可以帮助别人.我正在设置答案,因为许多问题已经解决,最终在本地工作,所以剩下的任何问题都可能与我的具体环境有关.

小智 7

您必须基于通过HTTP为tcp公开的元数据生成代理(确保httpGetEnabled设置为true).您在客户端使用的地址应该是托管地址.请参考以下帖子.

http://blogs.msdn.com/b/swiss_dpe_team/archive/2008/02/08/iis-7-support-for-non-http-protocols.aspx