【问题标题】:Can I use WCF duplex binding to relay message?我可以使用 WCF 双工绑定来中继消息吗?
【发布时间】:2009-08-04 12:10:02
【问题描述】:

我有一个客户端应用程序、一个服务器和另一个客户端,我们称之为第三方。作为合同的一部分,我有一个回调接口,由第三方和客户端实现。

第三方将调用服务器操作(方法)然后服务器将触发回调,但不会调用第三方的回调,而是调用客户端的回调实现。

【问题讨论】:

    标签: c# wcf binding callback duplex


    【解决方案1】:

    是的,你绝对可以这样做。

    最简单的方法是将您的服务实现为 PerSession 服务,并在初始化/构造时捕获回调上下文。通常情况下,我会将服务对象(此时真正代表一个连接)添加到内部核心对象。

    然后,当您收到来自客户端的消息时,您可以调用任何服务对象(而不是通过合同),并在内部将数据转发给关联的客户端。

    这是一个非常简单的概念实现,没有异常处理,还有一些非常糟糕的设计(静态类 BAD!)。我还没有对此进行测试,但即使我错过了跨越 i 或点 t,这些原则也应该成立。此示例还将调用转发到 所有 个客户端,但选择单个客户端遵循相同的基本模式。

    尝试使用单例服务来做到这一点会更加困难,而且每次调用服务显然行不通:)

    [ServiceContract(CallbackContract = typeof(ICallback))]
    public interface IContract
    {
        [OperationContract(IsOneWay = true)]
        void SendTheData(string s);
    }
    
    public interface ICallback
    {
        [OperationContract(IsOneWay = true)]
        void ForwardTheData(string s);
    }
    
    [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant, InstanceContextMode = InstanceContextMode.PerSession)]
    public class ServiceConnection : IContract
    {
        private ICallback m_callback;
    
        public ServiceConnection()
        {
            m_callback = OperationContext.Current.GetCallbackChannel<ICallback>();
            ServiceCore.Add(this);
        }
    
        public void SendTheData(string s)
        {
            ServiceCore.DataArrived(s);
        }
    
        public void SendToClient(string s)
        {
            m_callback.ForwardTheData(s);
        }
    }
    
    static public class ServiceCore
    {
        static private List<ServiceConnection> m_connections = new List<ServiceConnection>();
    
    
        public static void DataArrived(string s)
        {
            foreach(ServiceConnection conn in m_connections)
            {
                conn.SendTheData(s);
            }
        }
    
        public static void Add(ServiceConnection connection)
        {
            m_connections.Add(connection);
        }
    }
    

    【讨论】:

      【解决方案2】:

      通过快速阅读 Microsoft Duplex 服务文档,我认为这不会满足您的要求。可能还有其他一些聪明的功夫 WCF 方法可以做到这一点,但在我的例子中,我为服务器创建了一个“PassThruService”,它实现了与真实服务相同的合同,并将收到的任何请求发送到客户端。

      这是我的代码的一部分,它解释了它的主旨。

      private const int OPERATION_TIMEOUT = 5000;
      private MyServiceClient m_client = new MyServiceClient();
      
      public bool IsAlive() {
          try {
              logger.Debug("PassThruService IsAlive.");
      
              bool isAlive = false;
              ManualResetEvent isAliveMRE = new ManualResetEvent(false);
      
              m_client.IsAliveComplete += (s, a) => { isAlive = a.Result; isAliveMRE.Set(); };
              m_client.IsAliveAsync();
      
              if (isAliveMRE.WaitOne(OPERATION_TIMEOUT)) {
                  return isAlive;
              }
              else {
                  throw new TimeoutException();
              }
          }
          catch (Exception excp) {
              logger.Error("Exception PassThruService IsAlive. " + excp.Message);
              throw;
          }
      

      【讨论】:

        【解决方案3】:

        我不完全明白你在这里真正问的是什么......但无论如何我都会尝试提供一些提示。

        .NET 3.5 中的 WCF 不太支持中继消息或路由 - 基础设施已经存在,但手动设置仍然需要大量工作。

        我所知道的关于 .NET 3.5 中 WCF 的最佳介绍是 Michele Leroux Bustamante 在 MSDN 杂志上的一篇由两部分组成的文章:

        第 2 部分有一个关于双工路由器的部分 - 这对您的探索有帮助吗??

        .NET 4.0 中的 WCF 承诺为路由带来额外的支持 - 将有一个 RoutingService 基类,可用于编写路由服务,它将允许可配置的、基于内容或元数据的路由 - 不管正是你需要的。

        .NET 4.0 计划在今年晚些时候(2009 年)发布——希望如此!所以虽然这仍然是未来,但它看起来很美好!

        马克

        【讨论】:

          【解决方案4】:

          我想我找到了解决办法..

          这是链接。 http://msdn.microsoft.com/en-us/magazine/cc163537.aspx

          尝试查看图 6。这就是我想要实现的目标。

          【讨论】:

          • 看我的例子...我只用一个操作简化了它,但它是相同的模式。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-09-23
          • 1970-01-01
          • 2012-12-06
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多