2

好的,我有一个 WCF 服务,它的行为非常尴尬。问题是,当我调用服务方法时,如下所示:

using (var wcf = new Wcf<IDroneService>("http://test.group.com/DroneService.svc"))
{
    wcf.Channel.StartLoadTest(scenario);
}

直到请求在一分钟后超时之前什么都没有发生,但是只有在抛出异常之后,WCF 服务(托管在 IIS 中)才会启动,也就是说,实际加载它的程序集,并运行 Application_Start,实例化该服务服务器端的端点等,它继续正确接收请求并执行它。但是这只发生在请求超时并且抛出异常之后

这是我配置客户端和服务器绑定的方式:

public class WcfConfigurator
{
    public Binding GetBinding()
    {
        var basic = new BasicHttpBinding
        {
            MaxBufferSize = int.MaxValue,
            MaxBufferPoolSize = int.MaxValue,
            MaxReceivedMessageSize = int.MaxValue,
            TransferMode = TransferMode.Streamed,
            ReceiveTimeout = TimeSpan.FromSeconds(30),
            ReaderQuotas =
            {
                MaxDepth = int.MaxValue,
                MaxStringContentLength = int.MaxValue,
                MaxArrayLength = int.MaxValue,
                MaxBytesPerRead = int.MaxValue,
                MaxNameTableCharCount = int.MaxValue
            }
        };
        return basic;
    }

    public void ConfigureBehavior(ServiceEndpoint endpoint)
    {
        foreach (OperationDescription op in endpoint.Contract.Operations)
        {
            var dataContractBehavior = op.Behaviors.Find<DataContractSerializerOperationBehavior>();
            if (dataContractBehavior != null)
            {
                dataContractBehavior.MaxItemsInObjectGraph = int.MaxValue;
            }
        }
    }

    public void ConfigureBehavior(KeyedByTypeCollection<IServiceBehavior> behaviors)
    {
        var serviceDebugBehavior = behaviors.Find<ServiceDebugBehavior>();
        if (serviceDebugBehavior != null)
        {
            serviceDebugBehavior.IncludeExceptionDetailInFaults = Config.Wcf.ExceptionDetails;
        }
    }
}

我在服务器端使用相同的编程配置来构建端点。这个问题只出现在大信封上,对于较小的信封,这不是问题。

我在 Wcf 通道的配置中遗漏了什么吗?Wcf<T>只是一个包装ChannelFactory.CreateChannel; 在 WCF 服务器上,我也使用 Windsor WcfIntegration 工具以编程方式对其进行配置。像这样:

public override ServiceHostBase CreateServiceHost(string constructorString, Uri[] baseAddresses)
{
    ServiceHostBase serviceHost = base.CreateServiceHost(constructorString, baseAddresses);
    return ConfiguredServiceHost(serviceHost);
}

private T ConfiguredServiceHost<T>(T serviceHost) where T : ServiceHostBase
{
    serviceHost.AddDefaultEndpoints();

    wcfConfigurator.ConfigureBehavior(serviceHost.Description.Behaviors);

    foreach (ServiceEndpoint endpoint in serviceHost.Description.Endpoints)
    {
        endpoint.Binding = wcfConfigurator.GetBinding();
        wcfConfigurator.ConfigureBehavior(endpoint);
    }
    return serviceHost;
}

虽然我不认为这是服务器端问题(至少到目前为止不是),因为就像我说的那样,如果信封太大,WCF 服务器的符号甚至不会加载(直到请求超时,并且无论如何都已处理)。

有没有人遇到过这个奇怪的问题?

4

2 回答 2

0

根据我使用 WCF 的经验 - WCF 错误很难预测和诊断,需要深入调查并启用大量日志记录和 WCF 跟踪。我觉得客户端/服务器服务超时存在一些错误配置。所以安装最新版本的 Fiddler,看看发生了什么,发送了哪些请求,是否发送了响应。还可以使用 启用 WCF 跟踪switchLevel="All",在大多数情况下,WCF 跟踪日志会明确指出您的问题。

你提到1分钟...

WCF 中的超时及其默认值

这些是最著名的超时。SendTimeout, ReceiveTimeout,OpenTimeoutCloseTimeout. 它们可以通过配置或绑定上的代码轻松设置。这些的默认值为1 分钟

尝试显式增加其值,但首先我建议您了解问题所在,为什么会出现,因为 1 分钟建立连接就足够了。

于 2012-11-28T21:12:58.490 回答
0

我之前在使用 WCF 时也遇到过类似的问题,这导致我在使用服务时使用了 ChannelFactory。我知道它不能解释你的错误,但也许值得一试。我是这样做的:

internal static class ServiceObjects
{
    public static ISomeService SomeSVC { get { return GetSomeServiceClient(); }

    private static BasicHttpBinding _Binding = new BasicHttpBinding("SomeBasicHttpBindingEndpoint"); 
    private static EndpointAddress _Endpoint = new EndpointAddress(new Uri("http://test.helloworld.com/SomeService.svc"));

    private static IDocManagerService GetDocServiceClient()
    {
        ChannelFactory<ISomeService> _someSvcFactory = new ChannelFactory<ISomeService>(_Binding, _Endpoint);

        foreach (OperationDescription op in _someSvcFactory.Endpoint.Contract.Operations)
        {
            DataContractSerializerOperationBehavior _dataContractBehavior = op.Behaviors.Find<DataContractSerializerOperationBehavior>() as DataContractSerializerOperationBehavior;

            if (_dataContractBehavior != null)
            {
                _dataContractBehavior.MaxItemsInObjectGraph = int.MaxValue;
            }
        }

        return _someSvcFactory.CreateChannel();
    }
}

并使用服务:

ServiceObjects.SomeSVC.SomeMethod()
于 2013-01-16T09:16:24.860 回答