简体   繁体   English

wsDualHttpBinding总是超时,而其他服务则按预期工作

[英]wsDualHttpBinding always timeout, while other services work as expected

I currently develop several services (WCF) to work with TFS 2010. 我目前开发一些服务(WCF)以与TFS 2010一起使用。

Some of them use the event subscription tool, while others are consumed through the sharepoint portal, small wpf applications, etc. 其中一些使用事件订阅工具,而其他一些则通过共享点门户,小型wpf应用程序等使用。

I'm working on an application to administer some stuff in another server, such as send an IIS Reset request to the server, and I'm using wsDualHttpBinding so I can message the user the progress as everything happens, through callbacks. 我正在开发一个应用程序来管理另一台服务器中的某些内容,例如向服务器发送IIS重置请求,并且我正在使用wsDualHttpBinding,以便可以通过回调向用户通知一切进展情况。

But I can't even call the method in the service, because whenever the channel tries to open, I get timeout exceptions, no matter what my OpenTimeout is. 但是我什至无法调用服务中的方法,因为无论何时通道尝试打开,无论我的OpenTimeout是什么,我都会收到超时异常。

This is my config (client-side) 这是我的配置(客户端)

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.net>
        <connectionManagement>
            <add maxconnection="200"   address="*"  />
        </connectionManagement>
    </system.net>
    <system.serviceModel>
        <bindings>
            <wsDualHttpBinding>
                <binding name="WSDualHttpBinding_IReset" closeTimeout="00:01:00"
                    openTimeout="00:02:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
                    bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
                    maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
                    messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true">
                    <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                        maxBytesPerRead="4096" maxNameTableCharCount="16384" />
                    <reliableSession ordered="true" inactivityTimeout="00:10:00" />
                    <security mode="None">
                        <message clientCredentialType="Windows" negotiateServiceCredential="true" />
                    </security>
                </binding>
            </wsDualHttpBinding>
            <wsHttpBinding>
                <binding name="WSHttpBinding_IDeploy" closeTimeout="00:01:00"
                    openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
                    bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
                    maxBufferPoolSize="1524288" maxReceivedMessageSize="1279748152"
                    messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
                    allowCookies="false">
                    <readerQuotas maxDepth="32" maxStringContentLength="81925" maxArrayLength="163848"
                        maxBytesPerRead="9192" maxNameTableCharCount="16384" />
                    <reliableSession ordered="true" inactivityTimeout="00:10:00"
                        enabled="false" />
                    <security mode="None">
                        <transport clientCredentialType="Windows" proxyCredentialType="None"
                            realm="" />
                        <message clientCredentialType="Windows" negotiateServiceCredential="true" />
                    </security>
                </binding>
            </wsHttpBinding>
        </bindings>
        <client>
            <endpoint address="http://tfsserver:8080/TFSFacade/DeployFacade.svc"
                binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IDeploy"
                contract="DeployFacade.IDeploy" name="WSHttpBinding_IDeploy" />
            <endpoint address="http://tfsserver:8080/DeployService/ResetService.svc"
                binding="wsDualHttpBinding" bindingConfiguration="WSDualHttpBinding_IReset"
                contract="ResetService.IReset" name="WSDualHttpBinding_IReset" />
        </client>
    </system.serviceModel>
    <appSettings>
        <add key="CopiaLocalRollback" value="true"/>
        <add key="CopiaLocalPublish" value="true"/>
        <add key="ModoDiagnostico" value="false" />
        <add key="TempoTimeout" value="300000" />
    </appSettings>
</configuration>

Server-side: 服务器端:

<?xml version="1.0"?>
<configuration>
    <system.web>
        <compilation debug="true" targetFramework="4.0" />
    </system.web>
    <system.serviceModel>
        <serviceHostingEnvironment multipleSiteBindingsEnabled="true" aspNetCompatibilityEnabled="true">
            <baseAddressPrefixFilters>
                <add prefix="http://tfsserver:8080"/>
                <add prefix="http://tfsservices:8080"/>
                <add prefix="http://tfsservices:1001"/>
            </baseAddressPrefixFilters>
        </serviceHostingEnvironment>
        <bindings>
            <wsDualHttpBinding>
                <binding name="WSDualHttpBinding_ResetService" closeTimeout="00:01:00"
                openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
                bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
                maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
                messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true">
                    <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                        maxBytesPerRead="4096" maxNameTableCharCount="16384" />
                    <reliableSession ordered="true" inactivityTimeout="00:10:00" />
                    <security mode="None">
                        <message clientCredentialType="Windows" negotiateServiceCredential="true" />
                    </security>
                </binding>
            </wsDualHttpBinding>
        </bindings>
        <behaviors>
            <serviceBehaviors>
                <behavior name="EventServiceBehavior">
                    <serviceMetadata httpGetEnabled="true" />
                    <serviceDebug includeExceptionDetailInFaults="true" />
                </behavior>
                <behavior name="">
                    <serviceMetadata httpGetEnabled="true" />
                    <serviceDebug includeExceptionDetailInFaults="false" />
                </behavior>
            </serviceBehaviors>
        </behaviors>
        <services>
            <service behaviorConfiguration="EventServiceBehavior" name="DeployService.ResetService">
                <endpoint address="" binding="wsDualHttpBinding" bindingConfiguration="WSDualHttpBinding_ResetService"
                  contract="DeployService.Contracts.IReset" />
            </service>
        </services>
    </system.serviceModel>
    <system.webServer>
        <modules runAllManagedModulesForAllRequests="true"/>
    </system.webServer>
</configuration>

Contracts: 合约:

[ServiceContract(SessionMode = SessionMode.Required,
             CallbackContract = typeof(IResetCallback))]
public interface IReset
{
    [OperationContract]
    void ExecutarIISReset();
}

[ServiceContract]
public interface IResetCallback
{
    [OperationContract(IsOneWay = true)]
    void PumpMessage(string message);

    [OperationContract(IsOneWay = true)]
    void PumpResponsiveMessage(ResponsiveMessage message);

    [OperationContract(IsOneWay = true)]
    void PumpLogDeployBEMessage(LogDeployBE message);

    bool Confirmar();

    ServidorModel[] GetServidores();
}

Service (Not posting the code since the problem happens before it's reached): 服务(不发布代码,因为问题在解决之前就已发生):

[AspNetCompatibilityRequirementsAttribute(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)] 
public class ResetService : IReset
{
    //Stuff here
}

In fiddler I get this on client-side: 在提琴手中,我在客户端得到此信息:

7 202 HTTP tfsserver:8080 /DeployService/ResetService.svc 0 private resetman.vshost:9000

I get 202 several times, then time passes and the timeout occurs 我得到202次,然后时间过去,发生超时

Running fiddle on the server, I get absolutely nothing. 在服务器上运行小提琴,我什么也没得到。

What may be happening? 可能会发生什么?

EDIT: Weird, localhost works. 编辑:很奇怪,本地主机工作。 Does wsDualHttpBinding need special permissions or something? wsDualHttpBinding是否需要特殊权限或其他权限? Didn't find anything on the 'internets' 在“互联网”上找不到任何内容

Since you are using wsDualHttpBinding then both your server and your client need to be reachable on the ports specified in your config. 由于您正在使用wsDualHttpBinding因此服务器客户端都必须在配置中指定的端口上均可访问。 This is the reason it works on your local machine as you dont have any port issues. 这是它在本地计算机上运行的原因,因为您没有任何端口问题。 The timeout is consistent with a firewall blocking or your server unable to route back to your client. 超时与防火墙阻止或服务器无法路由回到客户端一致。

If your client can easily be reached by adding a firewall or port forwarding rule then wsDualHttpBinding may still be suitable - otherwise using wsDualHttpBinding is probably not ideal. 如果可以通过添加防火墙或端口转发规则轻松访问您的客户端,则wsDualHttpBinding可能仍然适用-否则,使用wsDualHttpBinding可能并不理想。 In this case you may need to have the client poll for messages instead of receiving them via the callback (ie client pulls messages instead of having them pushed via a callback) 在这种情况下,您可能需要让客户端轮询消息,而不是通过回调接收消息(即,客户端提取消息而不是通过回调推送消息)

See this post for more. 有关更多信息,请参见这篇文章。 and also this one. 还有这个

I was stuck with the same problem. 我陷入了同样的问题。 I have resolved the issue by passing my binding configuration to the service with the help of following code in client application. 通过在客户端应用程序中的以下代码的帮助下将绑定配置传递给服务,我已经解决了该问题。 This will give you an idea about how to achieve your goal. 这将使您对如何实现目标有所了解。 It worked for me in most of my systems but it still gives the timeout problem in some systems. 它在我的大多数系统中都对我有用,但在某些系统中仍然会出现超时问题。 Possible cause unable to bind the port. 可能的原因无法绑定端口。

      Service objService = new Service(objClass, "WSDualHttpBinding_ISendChatService");
            WSDualHttpBinding binding = objService.Endpoint.Binding as WSDualHttpBinding;
            int portNumber = FreeTcpPort();
            string hostName = Dns.GetHostName();
            binding.ClientBaseAddress = new Uri("http://"+Dns.GetHostByName(hostName).AddressList[0].ToString()+":" + portNumber + "/");            
            objService.Start(name);


static int FreeTcpPort()
        {
            TcpListener l = new TcpListener(IPAddress.Loopback, 0);
            l.Start();
            int port = ((IPEndPoint)l.LocalEndpoint).Port;
            l.Stop();
            return port;
        }

Try 尝试

  • ConcurrencyMode = ConcurrencyMode.Reentrant
  • InstanceContextMode = InstanceContextMode.Single
  • remove SessionMode.Required 删除SessionMode.Required

on your service behaviour 关于您的服务行为

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM