在Windows服务中托管WCF服务出现问题

13

我有一个托管在Windows服务中的WCF服务。Windows服务有一个像这样的OnStart方法:

protected override void OnStart(string[] args)
{
  serviceHost = new ServiceHost(typeof (RouterService));
  serviceHost.Open();
}

目前我的代码非常简单,因为我正在试图找到问题。由于我没有放置任何错误处理,所以此时的任何异常情况都会阻止服务正确地启动。服务会启动,然后立即停止。

我的WCF服务配置文件如下:

<?xml version="1.0"?>
<configuration>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
  </startup>
  <system.serviceModel>
    <services>
      <service name="WcfService.RouterService"
               behaviorConfiguration="serviceBehavior" >
        <endpoint address="RouterService" contract="WcfService.IRouterService" binding="wsHttpBinding" bindingConfiguration="NoSecurity" />
        <endpoint address="mex" contract="IMetadataExchange" binding="mexHttpBinding" />
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8000"/>
          </baseAddresses>
        </host>
      </service>
    </services>
    <bindings>
      <wsHttpBinding>
        <binding name="NoSecurity">
          <security mode="None" />
        </binding>
      </wsHttpBinding>
    </bindings>
    <behaviors>
      <serviceBehaviors>
        <behavior name="serviceBehavior" >
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>

另外,我已经添加了NETWORK SERVICE用户(服务正在运行的用户)以便能够在指定的端口上监听Http:

netsh http add urlacl url=http://+:8000/ user="NETWORK SERVICE"

现在,在客户端中,我选择添加服务引用。我可以找到服务器,VS也能创建配置并生成代理文件。然后在客户端内部,我创建了代理的实例,并打开了它。一切仍然很好。但是在调用代理的第一个方法时,我得到了以下异常:

The HTTP service located at http://localhost:8000/RouterService is too busy.

我知道我的客户端是唯一尝试连接此服务的东西,那么为什么会出现这个错误消息呢?如何修复它?当它尝试调用该方法时不会超时,它几乎立即抛出异常。

编辑

好的,现在我发现我的TestServer(不是Windows客户端,而是控制台应用程序)也显示相同的错误。早些时候它没有,WCF服务或TestServer也没有更改过。

然后我尝试将端口从8000改为8080,然后它就起作用了。然后我对Windows服务进行了相同的操作,也起作用了(在新端口上运行netsh http命令之后)

所以某些原因导致端口8000上的http出了问题。当然,我也尝试重新启动系统。

这让我感到困惑,如果有人知道这里发生了什么事情,我会很感激。


你的服务返回什么类型?我在返回不可序列化类型的服务中看到过这个问题。这也可能是由于服务主机的应用程序池未启动或类似原因引起的问题。 - Henric
1
我同意@daft的观点,该服务可能由于序列化问题无法返回数据类型。如果适用,应用程序池不应成为问题,因为它是相同的池(至少在IIS中),可以提供wsdl/config,从而允许您成功生成代理类。 - Smudge202
只是想澄清一下,你的服务确实在运行,对吧?而停止的情况是什么其他情况呢? - H H
@smudge和@daft - 这里现在出现了一些新的奇怪行为。请看我的编辑以获取更多澄清信息。 - Øyvind Bråthen
@smudge,@daft和@henk - 我现在已经解决了。如果您有兴趣了解为什么会发生这种情况,我已在下面添加了解决方案作为答案。感谢您抽出时间来查看此问题。 - Øyvind Bråthen
显示剩余2条评论
2个回答

13

好的,在长时间尝试了解发生了什么之后,我找到了解决方案。

我创建了 Windows 服务,并试图启动它,但无法启动,因为我必须首先注册 NETWORK SERVICE 用户以侦听 http post 8000。 因此我运行了以下命令:

netsh http add urlacl url=http://+:8000/RouterService user="NETWORK SERVICE"

它返回了成功结果,但是然后我尝试启动服务,并收到了相同的错误消息。 然后我运行了同一命令,但未指定 RouterService:

netsh http add urlacl url=http://+:8000/ user="NETWORK SERVICE"

它返回了成功结果,现在我的 Windows 服务已经可以正常启动,但我遇到了上述问题。

看来第一个 netsh 调用导致了所有这些问题。 我尝试使用以下命令再次将其删除:

netsh http delete urlacl url=http://+:8000/RouterService

然后一切都完美地工作了。

由于异常与实际问题无关,因此调试起来非常麻烦,因此希望这个问题能为其他人节省几个小时的时间 :)


4

考虑使用着名的SID字符串代替"user"命令行键,这将使您具有跨文化的可移植性(我在法语本地化的Win7机器上遇到了问题)。有关更多信息,请参见SID字符串。对于您的情况,这将是:

netsh http add urlacl url=http://+:8000/ sddl="O:NS"

MSDN上SDDL的链接


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接