【发布时间】:2013-05-13 18:19:16
【问题描述】:
我已经为此奋斗了好几天,实际上浏览了一百篇文章,提供了有关如何在 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 绑定
我还去了网站的高级设置并将启用的协议设置为http,net.tcp
我确保 Windows 功能非 HTTP 激活已启用(并重新启动)。这是一项 Windows 功能,因此请查找“打开或关闭 Windows 功能”来找到它。
确认网络应用程序正在运行
该网站适用于 Web 应用程序的其余部分。我将 test.mydomain.com 设置为指向我的 hosts 文件中的 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
交换错误 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://计算机名/SignalR/ServerHubService.svc。连接 尝试持续了 00:00:04.0002288 的时间跨度。 TCP错误代码 10061: 由于目标机器主动,无法建立连接 拒绝了。
这是包含在错误中的内部堆栈跟踪:
无法建立连接,因为目标机器主动 拒绝它 [2001:0:5ef5:79fb:3884:a:a547:b2fd]:808 at System.Net.Sockets.Socket.DoConnect(端点 endPointSnapshot, SocketAddress socketAddress) 在 System.Net.Sockets.Socket.Connect(EndPoint remoteEP) 在 System.ServiceModel.Channels.SocketConnectionInitiator.Connect(Uri uri,TimeSpan 超时)
如果您使用netstat -an |find /i "listening" 看到端口 808 上没有任何监听,可能是因为 Net.Tcp Listener Adapter 服务没有运行。
确认
呼叫现在进行,但需要进行一些确认才能宣布成功。我需要确认这实际上是对端口 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>
- baseAddress 调整为
- 已经在服务器本地和另一台服务器上使用客户端进行了测试。两者都可以通过 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 上到达服务器的调用,并可能确定调用不起作用的原因。但是,我目前不知道如何分析。
祝你好运
我放弃了,而是在套接字层实现了这一点。它立即起作用。不过,我希望这可以帮助其他人。我正在设置一个答案,因为许多问题都已解决,并且最终在本地工作,所以任何剩余的问题都可能与我的特定环境有关。
【问题讨论】:
-
您是否启用了 WCF 非 HTTP 激活组件? (详情在这里msdn.microsoft.com/en-us/library/ms731053.aspx)。您是否还为您的网站添加了 tcp 到允许的协议? (管理网站 -> 高级设置 -> 启用协议)。您是否尝试过基于通过 HTTP 公开的元数据生成代理? (test.mydomain.com/SignalR/ServerHubService.svc)
-
我忘记启用非 HTTP 激活(我只在我的测试服务器上做过)。不幸的是,启用此功能后我得到了同样的错误。我已经记住了高级设置下的 net.tcp,但现在已将其添加到问题详细信息中。如果我尝试基于 http 生成代理,我会收到一个有趣的错误 - 我将用这个更新问题。
标签: c# wcf wcf-binding net.tcp