[英]Setting up WCF TCP service in a web application
我已经和它斗争了好几天,实际上经历了一百篇文章,给出了如何在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
}
}
}
托管服务的应用程序的配置
在线教程之后,我在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绑定
我还进入了网站的高级设置,并将Enabled Protocols设置为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
尝试以客户端身份连接到服务
如果您不记得设置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:无法建立连接,因为目标计算机主动拒绝它。
这是包含在错误中的内部堆栈跟踪:
无法建立连接,因为目标计算机在System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot,SocketAddress socketAddress)处主动拒绝它[2001:0:5ef5:79fb:3884:a:a547:b2fd]:808 System.ServiceModel.Channels.SocketConnectionInitiator.Connect(Uri uri,TimeSpan timeout)中的.Net.Sockets.Socket.Connect(EndPoint remoteEP)
如果使用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
设置为808:*
? 是 http,net.tcp
? 是 netstat -an |find /i "listening"
查看 telnet mydomain.com 808
从外部telnet mydomain.com 808
登录到端口808上的服务器 net.tcp://mydomain.com:808/SignalR/ServerHubService.svc
localhost
,但在服务器上无法运行后更改为mydomain.com
: <identity><dns value="mydomain.com" /></identity>
服务器上可能缺少哪些配置? 我非常接近目标。 请协助我解决此问题并完成问题。
以下是调用服务的服务器上的客户端配置:
<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上到达服务器的呼叫,并可能确定呼叫无效的原因。 但是,我不知道目前如何分析这个问题。
祝好运
我放弃了并在套接字层实现了这一点。 它立即起作用。 不过,我希望这可以帮助别人。 我正在设置答案,因为许多问题已经解决,最终在本地工作,所以剩下的任何问题都可能与我的具体环境有关。
您必须基于通过HTTP为tcp公开的元数据生成代理(确保httpGetEnabled设置为true)。 您在客户端使用的地址应该是托管地址。 请参考以下帖子。
http://blogs.msdn.com/b/swiss_dpe_team/archive/2008/02/08/iis-7-support-for-non-http-protocols.aspx
在您的问题中,您提到您已连接到“test.mydomain.com”但错误已将服务器更改为“computername”。 然后在你的评论中你提到它仍然无法连接。 如果您希望在WSDL / MEX中返回别名,请在服务行为中添加useRequestHeadersForMetadataAddress节点。 以下是此节点上的MSDN信息: MSDN useRequestHeadersForMetadataAddress节点
这是您的配置应该如何。 这考虑了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>
在IIS中托管基于TCP的服务始终是一个负担。 WCF使您可以非常轻松地运行自己的服务主机,监听TCP端口。 我的建议是这样做,并将其设置为作为Windows服务运行。
请参阅此文章: http : //msdn.microsoft.com/en-us/library/ff649818.aspx
我猜您遇到的问题是您需要为您的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
- 具有Windows身份验证的Intranet上的WCF
- 对于以下帖子,尝试阅读一个不被接受的答案: 我需要为net.tcp服务设置什么SPN?
您是否尝试在本地计算机上的Windows服务中托管服务(用于测试目的)? 这样您至少可以知道问题出在服务端还是IIS /服务器配置上。
您在服务器上运行Net.TCP端口共享服务我猜...没有明确说明它。
今天我遇到了类似的问题,同时从asp.net web api中调用net.tcp wcf服务。 我不会说这个服务已经工作了多年的所有其他机器,但是调用是由wcf自托管,wcf iis asp.net兼容托管 - >反对net.tcp服务自托管。 然后我发布了我的简单web api调用相同的net.tcp服务,一切都出错,并且所有连接都没有任何理由中止,即使完整的wcf跟踪双方(服务和客户端)都没有帮助,只是告诉同样的“连接中止”。
我已经知道net.tcp带有启用传输的安全性,使用Windows身份验证来签名和加密通信,所以,我只是试图关闭安全性,一切都开始正常工作。
试试这两种方式(客户端和服务)关闭安全性:
<security mode="None"/>
全服务绑定:
<netTcpBinding>
<binding name="netTcpBinding" portSharingEnabled="true">
<security mode="None"/>
</binding>
</netTcpBinding>
我希望这对你也有帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.