这两天翻了很多关于回调资料,后来才恍然大悟,贴上来说下解决方案。
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); }
}
新闻热点
疑难解答