這兩天翻了很多關于回調資料,后來才恍然大悟,貼上來說下解決方案。
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); }
}

新聞熱點
疑難解答