WCF回调实现

这两天翻了很多关于回调资料,后来才恍然大悟,贴上来说下解决方案。

1. 回调接口声明

    public interface ICallback
    {
        [OperationContract(IsOneWay = true)] // 回调操作也必须One Way  
        void CallbackToClient(DateTime timestamp, string message);
    }

2.回调使用

/// <summary>
    /// 设置服务行为为单例模式,即所有客户端共享一个服务实例
    /// </summary>
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple)]
    public class MyTagService : IService
    {

           static List<ICallback> m_Callbacks = new List<ICallback>();

           public void AddMessage(string message)
        {
            m_Callbacks.ForEach(callback =>
            {
                if (((ICommunicationObject)callback).State == CommunicationState.Opened)
                    callback.CallbackToClient(DateTime.Now, message);
                else
                    m_Callbacks.Remove(callback);
            });

         }

       

       /// <summary>
        /// read from plc and update local value
        /// </summary>
        /// <param name="plcTag">需要读取PLC的变量</param>
        /// <returns>无</returns>
        public string Read_PLC_Tag(PLCTag tag)
        {
            string value=plc.TagValue(tag);
            if (ServerMessageGot != null)
            {
                ServerMessageGot(this, new MessageReceiveEventArgs(DateTime.Now,tag.Address.ToString() + "-" + tag.DataSize.ToString() + "-" + value.ToString()));
            }


            AddMessage(tag.Address.ToString() + "-" + tag.DataSize.ToString() + "-" + value.ToString());     //回调
            
            return value;
        }

    }

3. 回调事件

///<summary>  
    ///实现回调接口  
    ///</summary>  
     [CallbackBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, UseSynchronizationContext = false)]
    public class MyCallback : ICallback
    {
        /// <summary>  
        // 回调后触发该事件,用于通知客户端  
        /// </summary>  
         public event EventHandler<MessageReceiveEventArgs> ValueCallbacked = delegate { };
        // 因为该方法是由服务器调用的  
        // 如果希望在客户端能即时作出响应  
        // 应当使用事件  
        public void CallbackToClient(DateTime timestamp, string message)
        {
            MessageReceiveEventArgs e = new MessageReceiveEventArgs(timestamp,message);
            if (this.ValueCallbacked != null)
            {
                this.ValueCallbacked(this, e);
            }
        }
    }


4.客户端回调

 public class Client 
    {
        IService ClientChanel;
        DuplexChannelFactory<IService> channelFactory;
        MyCallback Callback = new MyCallback();
        
        /// <summary>
        /// 服务端对客户端的消息通知
        /// </summary>
        public event EventHandler<MessageReceiveEventArgs> ServerMessageReceived = delegate { };


        public Client(string ServerName)
        {
            NetTcpBinding binding = new NetTcpBinding();
            binding.Security.Mode = SecurityMode.None;


            InstanceContext instanceContext = new InstanceContext(Callback);
            channelFactory = new DuplexChannelFactory<IService>(instanceContext, binding, new EndpointAddress("net.tcp://" + ServerName + ":2970/PLCTagServices/"));
            ClientChanel=channelFactory.CreateChannel();
            ClientChanel.Subscribe();
            channelFactory.Faulted += new EventHandler(channelFactory_Faulted);
            
            Callback.ValueCallbacked+=new EventHandler<MessageReceiveEventArgs>(Callback_ValueCallbacked);
        }
        
        void Callback_ValueCallbacked(object sender,MessageReceiveEventArgs e)
        {
            ServerMessageReceived(this, e);
        }

}



  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
WCF路由是一种将消息从一个端点路由到另一个端点的机制,可以在WCF服务中使用,也可以在非WCF环境中使用。在SOAP协议下,WCF路由可以通过以下步骤实现: 1. 创建一个路由服务,并为其配置路由表。路由表定义了输入消息如何被路由到目标服务。 2. 配置源服务,使其将消息发送到路由服务。可以通过配置终结点来实现。 3. 配置目标服务,使其能够接收路由服务转发的消息。同样可以通过配置终结点来实现。 4. 测试路由服务是否能够正确地将消息路由到目标服务。可以使用WCF Test Client或其他SOAP客户端来进行测试。 下面是一个简单的WCF路由示例,以演示如何实现SOAP协议下的WCF路由: 1. 创建一个名为“RoutingService”的路由服务,并为其配置路由表。在路由表中,将输入消息路由到目标服务的终结点上。 ```xml <system.serviceModel> <services> <service name="System.ServiceModel.Routing.RoutingService"> <endpoint address="" binding="basicHttpBinding" contract="System.ServiceModel.Routing.IRequestReplyRouter" /> <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> </service> </services> <routing> <filters> <filter name="MyFilter" filterType="MatchAll" /> </filters> <filterTables> <filterTable name="MyFilterTable"> <add filterName="MyFilter" endpointName="MyEndpoint" /> </filterTable> </filterTables> </routing> <client> <endpoint name="MyEndpoint" address="http://localhost:8000/MyService" binding="basicHttpBinding" contract="IMyService" /> </client> </system.serviceModel> ``` 2. 配置源服务的终结点,使其将消息发送到路由服务。 ```xml <system.serviceModel> <services> <service name="MyService"> <endpoint address="" binding="basicHttpBinding" contract="IMyService" /> <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> </service> </services> <client> <endpoint name="RoutingEndpoint" address="http://localhost:8001/RoutingService" binding="basicHttpBinding" contract="System.ServiceModel.Routing.IRequestReplyRouter" /> </client> </system.serviceModel> ``` 3. 配置目标服务的终结点,使其能够接收路由服务转发的消息。 ```xml <system.serviceModel> <services> <service name="MyService"> <endpoint address="" binding="basicHttpBinding" contract="IMyService" /> <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> </service> </services> </system.serviceModel> ``` 4. 测试路由服务是否能够正确地将消息路由到目标服务。 可以使用WCF Test Client或其他SOAP客户端来测试路由服务是否能够正确地将消息路由到目标服务。在测试之前,确保源服务和目标服务都已启动,并且路由服务已被正确配置。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值