none
WCF回调超时的问题 RRS feed

  • 问题

  • /// <summary>
        /// WCF 访问的服务契约
        /// </summary>
        [ServiceContract(CallbackContract = typeof(IServiceCallback))]
        public interface IService
        {
            /// <summary>
            /// 执行添加操作
            /// </summary>
            [OperationContract]
            [TransactionFlow(TransactionFlowOption.Allowed)]
            void Insert(DataPortal data);
    
            /// <summary>
            /// 执行更新操作
            /// </summary>
            [OperationContract]
            [TransactionFlow(TransactionFlowOption.Allowed)]
            void Update(DataPortal data);
    
            /// <summary>
            /// 执行删除操作
            /// </summary>
            [OperationContract]
            [TransactionFlow(TransactionFlowOption.Allowed)]
            void Delete(DataPortal data);
            
            /// <summary>
            /// 执行查询操作
            /// </summary>
            [OperationContract]
            void Load(DataPortal data);
        }
    
        /// <summary>
        /// WCF 服务回调接口
        /// </summary>
        [ServiceContract]
        public interface IServiceCallback
        {
            /// <summary>
            /// 服务器端在执行过程中时调用
            /// </summary>
            /// <param name="sender">触发该事件的对象</param>
            /// <param name="e">引发的 YiYou.Wcf.OperatingEventArgs 事件</param>
            [OperationContract(IsOneWay = true)]
            void OnProcessing(object sender, OperatingEventArgs e);
    
            /// <summary>
            /// 服务器端在执行过程中时调用
            /// </summary>
            /// <param name="sender">触发该事件的对象</param>
            /// <param name="e">引发的 YiYou.Wcf.OperatedEventArgs 事件</param>
            [OperationContract(IsOneWay = true)]
            void OnCompleted(object sender, OperatedEventArgs e);
        }

    /// <summary>
        /// 服务契约的实现
        /// </summary>
        [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Reentrant)]
        public class Service : IService
        {
            /// <summary>
            /// 添加
            /// </summary>
            public void Insert(DataPortal data)
            {
            }
    
            /// <summary>
            /// 更新
            /// </summary>
            public void Update(DataPortal data)
            {
            }
    
            /// <summary>
            /// 删除
            /// </summary>
            public void Delete(DataPortal data)
            {
            }
    
            /// <summary>
            /// 加载
            /// </summary>
            public void Load(DataPortal data)
            {
                IServiceCallback callback = OperationContext.Current.GetCallbackChannel<IServiceCallback>();
                callback.OnProcessing(null, new OperatingEventArgs(OperationAction.Load));
            }
        }

    private void button1_Click(object sender, EventArgs e)
            {
                InstanceContext context = new InstanceContext(new ClientCallback());
                NetTcpBinding binding = new NetTcpBinding();
                EndpointAddress address = new EndpointAddress("net.tcp://localhost:9901/Client.svc");
                using (DuplexChannelFactory<IService> channel = new DuplexChannelFactory<IService>(context, binding, address))
                {
                    IService service = channel.CreateChannel();
                    DataPortal data = new DataPortal();
                    using (service as IDisposable)
                    {
                        service.Load(data);
                    }
                }
            }
    
    
    
    public class ClientCallback : YiYou.Wcf.IServiceCallback
        {
            public void OnProcessing(object sender, YiYou.Wcf.OperatingEventArgs e)
            {
                Console.WriteLine("OnProcessing:" + e.Action);
            }
    
            public void OnCompleted(object sender, YiYou.Wcf.OperatedEventArgs e)
            {
                Console.WriteLine("OnCompleted");
            }
        }

    还有一个异常是在客户端 Callback的时候提示: “服务器未提供有意义的回复;这可能是由协定不匹配、会话过早关闭或内部服务器错误引起的。”

    在:callback.OnProcessing(new DataPortal(), new OperatingEventArgs(OperationAction.Load));

    服务器配置:

    <behaviors>
          <serviceBehaviors>
            <behavior>
              <dataContractSerializer maxItemsInObjectGraph="6553600"/>
            </behavior>
          </serviceBehaviors>
        </behaviors>
        <bindings>
          <netTcpBinding>
            <binding name="customTcpBindding" maxReceivedMessageSize="2147483647">
              <security mode="None" />
              <readerQuotas  maxDepth="32" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
            </binding>
          </netTcpBinding>
        </bindings>

    客户端配置:
    <system.serviceModel>
        <bindings>
          <netTcpBinding>
            <binding name="customNetTcpBinding" maxReceivedMessageSize="2147483647" maxBufferSize="2147483647">
              <security mode="None" />
              <readerQuotas maxDepth="32" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />          
            </binding>        
          </netTcpBinding>
        </bindings>
      </system.serviceModel>


    2012年7月22日 10:35

答案

全部回复

  • 怎么都没人回应?

    超时问题已经解决,用了 [CallbackBehavior(UseSynchronizationContext = false)] 标记客户端的ClientCallback 类

    还有 “服务器未提供有意义的回复;这可能是由协定不匹配、会话过早关闭或内部服务器错误引起的。” 没能解决

    public void Load(DataPortal data)
    {
        IServiceCallback callback = OperationContext.Current.GetCallbackChannel<IServiceCallback>();
        // callback.OnProcessing(null, new OperatingEventArgs(OperationAction.Load)); // 这样执行是正常
        callback.OnProcessing(new DataPortal(), new OperatingEventArgs(OperationAction.Load)); // 抛出异常
    }

    当 OnProcessing 第一个参数为 null 或值类型的时候都正常能够 Callback, 当为自定义类型的时候,就抛出异常 “服务器未提供有意义的回复;这可能是由协定不匹配、会话过早关闭或内部服务器错误引起的。”

    2012年7月23日 13:07
  • 怎么都没人回应?

    超时问题已经解决,用了 [CallbackBehavior(UseSynchronizationContext = false)] 标记客户端的ClientCallback 类

    还有 “服务器未提供有意义的回复;这可能是由协定不匹配、会话过早关闭或内部服务器错误引起的。” 没能解决

    public void Load(DataPortal data)
    {
        IServiceCallback callback = OperationContext.Current.GetCallbackChannel<IServiceCallback>();
        // callback.OnProcessing(null, new OperatingEventArgs(OperationAction.Load)); // 这样执行是正常
        callback.OnProcessing(new DataPortal(), new OperatingEventArgs(OperationAction.Load)); // 抛出异常
    }

    当 OnProcessing 第一个参数为 null 或值类型的时候都正常能够 Callback, 当为自定义类型的时候,就抛出异常 “服务器未提供有意义的回复;这可能是由协定不匹配、会话过早关闭或内部服务器错误引起的。”

    错误提示了,可能是绑定不匹配。你这里的配置有问题。

    服务启动的时候使用的是代码设置绑定,但是你配置文件里 指定的配置数据和默认的是不一致的。

    NetTcpBinding binding = new NetTcpBinding();
               
    EndpointAddress address = new EndpointAddress("net.tcp://localhost:9901/Client.svc");
               
    using (DuplexChannelFactory<IService> channel = new DuplexChannelFactory<IService>(context, binding, address))
               
    {
    -------------------------你要忙全部使用默认的配置,要忙全部使用配置文件里一致的数据。


    Frank Xu Lei--谦卑若愚,好学若饥
    [老徐的网站]:http://www.frankxulei.com/

    [老徐的博客]:http://54peixun.com/Author/frankxulei
    微软WCF中文技术论坛
    微软WCF英文技术论坛

    Windows Azure中文技术论坛

    2012年7月23日 13:41
    版主
  • NetTcpBinding binding = new NetTcpBinding("customNetTcpBinding");

    还不行呢,请指教。

    2012年7月25日 8:53
  • NetTcpBinding binding = new NetTcpBinding("customNetTcpBinding");

    还不行呢,请指教。

    你对比了2端的参数嘛?保证一致

    <netTcpBinding> <binding name="customTcpBindding" maxReceivedMessageSize="2147483647"> <security mode="None" /> <readerQuotas maxDepth="32" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" /> </binding> </netTcpBinding>

    这个配置文件里的参数 一定要和 客户端一致 尽量一致


    Frank Xu Lei--谦卑若愚,好学若饥
    [老徐的网站]:http://www.frankxulei.com/

    [老徐的博客]:http://54peixun.com/Author/frankxulei
    微软WCF中文技术论坛
    微软WCF英文技术论坛

    Windows Azure中文技术论坛

    2012年7月25日 10:07
    版主
  • 问题终于解决,配置文件我一个个对了,没有什么问题

    问题在 IServiceCallback 中

    [ServiceContract]
        public interface IServiceCallback
        {
            /// <summary>
            /// 服务器端在执行过程中时调用
            /// </summary>
            /// <param name="sender">触发该事件的对象</param>
            /// <param name="e">引发的 YiYou.Wcf.OperatingEventArgs 事件</param>
            [OperationContract(IsOneWay = true)]
            void OnProcessing(object sender, OperatingEventArgs e);
    
            /// <summary>
            /// 服务器端在执行过程中时调用
            /// </summary>
            /// <param name="sender">触发该事件的对象</param>
            /// <param name="e">引发的 YiYou.Wcf.OperatedEventArgs 事件</param>
            [OperationContract(IsOneWay = true)]
            void OnCompleted(object sender, OperatedEventArgs e);
        }

    void OnProcessing(object sender, OperatingEventArgs e);

    第一个参数的类型不能为 object,改为:void OnProcessing(DataPortal sender, YiYou.Wcf.OperatingEventArgs e) 之后就正常了

    即使加了 ServiceKnowType 也不行,也不知道为什么?徐哥能帮解释一下原因?

    2012年7月25日 15:53
  • ServieKnowType 只对继承类有效

    比如

    class RuntimeClass;

    class DataPortal : public RuntimeClass;

    接口中使用 RuntimeClass,传递 DataPortal 也能正确识别。

    2012年7月26日 9:03