using System; using System.Collections.Generic; using System.Timers; namespace EGFramework { //before use this module,you should install NewtonSoft.Json Nuget Package //in vscode,you can install this package by install vscode extension NuGet Package Manager GUI //search 'Newton' and choose Newtonsoft.Json //EGMessage, Every Message tools will be based in this class public class EGMessage : EGModule { public EasyEvent OnDataReceived { set; get; } = new EasyEvent(); public EasyEvent OnResponse { set; get; } = new EasyEvent(); public EasyEvent OnRequest { set; get; } = new EasyEvent(); /// /// Send delay in millisecond,if you don't need a Timer to delay send message,you can set it to 0. /// /// public int SendDelay { set; get; } = 100; public Queue RequestCache { set; get; } = new Queue(); private System.Timers.Timer RequestTimer { set; get; } public override void Init() { if(SendDelay>0){ RequestTimer = new System.Timers.Timer(SendDelay); RequestTimer.Elapsed += ExecuteRequest; RequestTimer.AutoReset = true; RequestTimer.Enabled = true; } } #region ReceiveFunctions private void ReceiveResponse(ResponseMsg msg) where T :IResponse, new() { this.ExecuteResponse(new T(),msg.stringData,msg.byteData,msg.sender,msg.protocolType); } /// /// Start to receive type of T data /// /// Data class of message public void OnReceive() where T : IResponse, new() { OnDataReceived.Register(ReceiveResponse); } /// /// Stop to receive type of T data /// /// Data class of message public void OffReceive() where T : IResponse, new() { OnDataReceived.UnRegister(ReceiveResponse); } #endregion #region request & response public void SendRequest(TRequest request,string sender,ProtocolType protocolType) where TRequest:IRequest { if(SendDelay>0){ RequestCache.Enqueue(new RequestMsgEvent(request,sender,protocolType)); }else{ OnRequest.Invoke(new RequestMsgEvent(request,sender,protocolType)); } //ExecuteRequest(); //OnRequest.Invoke(requestCache.Dequeue()); } private void ExecuteRequest(object source, ElapsedEventArgs e){ if(RequestCache.Count>0){ OnRequest.Invoke(RequestCache.Dequeue()); } } private void ExecuteResponse(TResponse response,string protocolString,byte[] protocolBytes,string sender,ProtocolType protocolType) where TResponse:IResponse { bool isSet = response.TrySetData(protocolString,protocolBytes); if (isSet) { //this.SendEvent(new ResponseMsgEvent(response, sender)); OnResponse.Invoke(new ResponseMsgEvent(response,sender,protocolType)); } } #endregion public void SetDelay(int millisecond){ this.SendDelay = millisecond; } } #region interface public interface IResponse { /// /// Attempt to fill in the data. If it does not comply with the relevant protocol rules, it is recommended to return false. If false is returned here, the data response will be ignored. /// /// original received /// bool TrySetData(string protocolData,byte[] protocolBytes); } public interface IRequest { /// /// define you message info in this function,and this return will be send to server&client by request. /// /// request info string ToProtocolData(); byte[] ToProtocolByteData(); } #endregion #region AbstractClass public class BaseJsonResponse : IResponse { private string ExceptionMsg; public virtual string ToProtocolData() { return ""; } public virtual bool TrySetData(string json,byte[] bytes) { try { return true; } catch (Exception e) { ExceptionMsg = e.ToString(); //PrintErr(ExceptionMsg); return false; } } } public class StringRequest : IRequest { private string RequestStr; public StringRequest() { RequestStr = "No message"; } public StringRequest(string str) { RequestStr = str; } public byte[] ToProtocolByteData() { return null; } public string ToProtocolData() { return RequestStr; } } #endregion #region Extension public static class CanRegisterMessageExtension { /// /// To register event until message received,if you only need message,please use: /// this.RegisterMessageEvent(e=>{ //To execute your message}) /// if you want to get sender,you also can to: /// this.RegisterMessageEvent((res,sender))=>{ //To execute your message /// Print(res.toProtocolData()); /// Print(sender); /// }) /// /// /// /// /// public static IUnRegister EGRegisterMessageEvent(this IEGFramework self, Action onEvent)where TResponse : IResponse { return EGArchitectureImplement.Interface.GetModule().OnResponse.Register(e=> { if (e.res.GetType() == typeof(TResponse)) { onEvent.Invoke((TResponse)e.res); } }); } /// /// To register event until message received,if you only need message,please use: /// this.RegisterMessageEvent(e=>{ //To execute your message}) /// if you want to get sender,you also can to: /// this.RegisterMessageEvent((res,sender))=>{ //To execute your message /// Print(res.toProtocolData()); /// Print(sender); /// }) /// /// /// /// /// public static IUnRegister EGRegisterMessageEvent(this IEGFramework self, Action onEvent)where TResponse : IResponse { return EGArchitectureImplement.Interface.GetModule().OnResponse.Register(e=> { if (e.res.GetType() == typeof(TResponse)) { onEvent.Invoke((TResponse)e.res,e.sender); } }); } public static IUnRegister EGRegisterMessageEvent(this IEGFramework self, Action onEvent)where TResponse : IResponse { return EGArchitectureImplement.Interface.GetModule().OnResponse.Register(e=> { if (e.res.GetType() == typeof(TResponse)) { onEvent.Invoke((TResponse)e.res,e.sender,e.protocolType); } }); } /// /// Start to receive type of TResponse data /// /// /// public static void EGOnMessage(this IEGFramework self) where TResponse : IResponse,new() { EGArchitectureImplement.Interface.GetModule().OnReceive(); } /// /// Stop to receive type of TResponse data /// /// /// public static void EGOffMessage(this IEGFramework self) where TResponse : IResponse,new() { EGArchitectureImplement.Interface.GetModule().OffReceive(); } } public static class CanSendMessageExtension { /// /// to send message by request and define sender /// /// /// /// /// public static void EGSendMessage(this IEGFramework self, TRequest request,string sender,ProtocolType protocolType)where TRequest : IRequest { EGArchitectureImplement.Interface.GetModule().SendRequest(request,sender,protocolType); } } /// /// this extension to link with protocol tools,such as tcp,udp,serial port,etc... /// public static class EGMessageEventExtension{ public static void EGOnReceivedData(this IModule self, ResponseMsg receivedData) { EGArchitectureImplement.Interface.GetModule().OnDataReceived.Invoke(receivedData); } public static void EGRegisterSendAction(this IModule self, Action sendAction){ EGArchitectureImplement.Interface.GetModule().OnRequest.Register(sendAction); } } #endregion #region event public struct ResponseMsg { public string sender; public string stringData; public byte[] byteData; public ProtocolType protocolType; public ResponseMsg(string stringData_,byte[] byteData_,string sender_,ProtocolType protocolType_) { stringData = stringData_; byteData = byteData_; sender = sender_; protocolType = protocolType_; } } public struct ResponseMsgEvent { public IResponse res; public string sender; public ProtocolType protocolType; public ResponseMsgEvent(IResponse res_,string sender_,ProtocolType protocolType_) { res = res_; sender = sender_; protocolType = protocolType_; } } public struct RequestMsgEvent { public IRequest req; public string sender; public ProtocolType protocolType; public RequestMsgEvent(IRequest req_ ,string sender_,ProtocolType protocolType_) { req = req_; sender = sender_; protocolType = protocolType_; } } #endregion public enum ProtocolType{ TCPClient = 0x00, TCPServer = 0x01, UDP = 0x02, SerialPort = 0x03, WebSocketClient = 0x10, WebSocketServer = 0x11, HttpServer = 0x20, HttpGet = 0x21, HttpPost = 0x22, HttpPut = 0x23, HttpPatch = 0x24, HttpDelete = 0x25, DLTSClient = 0x30, DLTSServer = 0x31, SSLClient = 0x40, SSLServer = 0x41 //MQTT,SSH,etc... } }