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

时间:2013-05-18 19:53:35

标签: c# wcf wcf-binding net.tcp

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

当前状态

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

我将针对此详细信息创建一个新问题,如果我从中获得结果,请使用答案更新此问题。

代码

我使用以下内容创建了ServerHubService.svc

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

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

在线教程之后,我在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>

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

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

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

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

bindings in IIS

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

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

enter image description here

确认网络应用程序正在运行

该网站适用于其余的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

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

如果您不记得设置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元数据   包含无法解析的引用:   &#39;的net.tcp://computername/SignalR/ServerHubService.svc/mex' ;.不能   connect to 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:无法建立连接,因为目标计算机是主动的   拒绝了。

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

  

无法建立连接,因为目标计算机是主动的   拒绝了它[2001:0:5ef5:79fb:3884:a:a547:b2fd]:808 at   System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot,   SocketAddress(socketAddress)at   System.Net.Sockets.Socket.Connect(EndPoint remoteEP)at   System.ServiceModel.Channels.SocketConnectionInitiator.Connect(URI   uri,TimeSpan超时)

如果您使用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服务是否正在运行?是
  • 绑定到net.tcp的IIS网站是否设置为808:*?是
  • IIS中的网站的高级设置下的启用协议设置为http,net.tcp?是
  • 服务器是否在端口808上侦听?是的,使用netstat -an |find /i "listening"
  • 进行了检查
  • 防火墙是否打开了端口808?是。
    • 服务器上的防火墙已关闭。
    • 我可以通过telnet mydomain.com 808
    • 从外部远程登录到端口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>

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

不是随意尝试很多东西,而是一个好问题:或许如何调试这样的东西? 我是否可以在任一服务器上安装一个程序,告诉我为什么要阻止此通话?

通过这样配置Wireshark,可以查看端口808上到达服务器的呼叫,并可能确定呼叫无法正常工作的原因。但是,我现在不知道如何分析它。

wireshark

祝你好运

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

7 个答案:

答案 0 :(得分: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

答案 1 :(得分:2)

在您的问题中,您提到您已连接到“test.mydomain.com”但错误已将服务器更改为“computername”。然后在你的评论中你提到它仍然无法连接。如果您希望在WSDL / MEX中返回别名,请在服务行为中添加useRequestHeadersForMetadataAddress节点。以下是此节点上的MSDN信息:MSDN useRequestHeadersForMetadataAddress node

这是配置的外观。这考虑了Prasath给出的答案(httpGetEnabled =“true”)。

<serviceBehaviors>
   <behavior name="ServerHubBehavior">
      <serviceMetadata httpGetEnabled="true" />
      <serviceDebug includeExceptionDetailInFaults="false" />
      <useRequestHeadersForMetadataAddress>
         <defaultPorts>
            <add scheme="net.tcp" port="808" />
         </defaultPorts>
      </useRequestHeadersForMetadataAddress>
   </behavior>
</serviceBehaviors>

答案 2 :(得分:0)

在IIS中托管基于TCP的服务一直是一个负担。 WCF使您可以非常轻松地运行自己的服务主机,监听TCP端口。我的建议是这样做并将其设置为以Windows服务运行。

请参阅此文章:http://msdn.microsoft.com/en-us/library/ff649818.aspx

答案 3 :(得分:0)

我猜您遇到的问题是您需要为您的WCF服务(在计算机上)设置SPN(服务主体名称),并将其添加到运行该服务的服务帐户。

如果您在默认应用程序池用户下运行它,则需要为该计算机配置SPN。

我知道这很令人不安,一旦我们的服务准备好部署到生产环境或预生产环境,通常会让我们感到惊讶。

在身份验证过程中,Kerberos会使用SPN。

尝试使用本机的IP来解析您的服务而不是主机名。 (这不应该要求SPN),用机器IP地址替换“test.mydomain.com”:

<host>
    <baseAddresses>
        <add baseAddress="net.tcp://192.168.0.253:808/SignalR/ServerHubService.svc" />
    </baseAddresses>
</host>

看看这些文章: - Kerberos for the Busy Admin
- WCF on intranet with windows authentication
- 对于以下帖子,请尝试阅读未被接受的答案:What SPN do I need to set for a net.tcp service?

答案 4 :(得分:0)

您是否尝试在本地计算机上的Windows服务中托管服务(用于测试目的)?这样您至少可以知道问题出在服务端还是IIS /服务器配置上。

答案 5 :(得分:0)

我猜服务器上有Net.TCP Port sharing service running ...没有明确说明。

答案 6 :(得分:0)

我今天遇到了类似的问题,同时从asp.net web api中调用net.tcp wcf服务。我不会说这个服务已经工作了多年的所有其他机器,但是调用是通过wcf自托管,wcf iis asp.net兼容主机 - &gt;反对net.tcp服务自托管。然后我发布了我的简单web api调用相同的net.tcp服务,一切都出错,并且所有连接都没有任何理由中止,即使完整的wcf跟踪双方(服务和客户端)都没有帮助,只是告诉同样的“连接中止”。

我已经知道net.tcp带有启用传输的安全性,使用Windows身份验证来签名和加密通信,所以,我只是试图关闭安全性,一切都开始正常工作。

尝试以这种方式关闭安全性(客户端和服务):

<security mode="None"/>

全服务绑定:

<netTcpBinding>

    <binding name="netTcpBinding" portSharingEnabled="true">

        <security mode="None"/>

    </binding>

</netTcpBinding>

我希望这也可以帮助你。