场景:
一个服务端(S), n个客户端(C1,C2...Cn), Cx1 通过 S 调用 Cx2 ,x1,x2属于{1,2,3...n},上指定的方法
采用WCF,并且采用泛型 实现强类型编程
过程,C1在S上发出消息(通过消息推送服务器),C2收到消息后,执行方法并上报进度与结果
注意
IIS中AppDomain是否是一个的
C2上的消息处理不在UI线程,
步骤1:
定于输入输出类,声明接口并定于实现(调用模板方法)
输入输出结构--注意命名空间跟类名要C与S端一致
public class TestARequest { public long Id { get; set; } public String Name { get; set; } public List<String> Items { get; set; } } public class TestAResponse { public long Id { get; set; } public String Name { get; set; } public List<String> Items { get; set; } }
接口与实现
public LongInvokeBucketInfo TestAStartInvoke(string position, string methodName, TestARequest request) { Action<LongInvokeBucket> nofityAct = (bucket) => { NotifyUtil.PostCSCNotify(bucket.Guid, position, methodName,null); }; return LongInvokeBucketMgr.StartInvoke4CSC<TestARequest, TestAResponse>(nofityAct,request); } public LongInvokeResponse<TestAResponse> TestALoopInvoke(LongInvokeBucketInfo request) { return LongInvokeBucketMgr.LoopInvoke<TestAResponse>(request); } public String TestARefreshInvoke(LongInvokeResponse<TestAResponse> request) { return LongInvokeBucketMgr.RefreshInvoke(request); } public LongInvokeResponse<TestARequest> TestALoadInvokeParam(String guid) { return LongInvokeBucketMgr.LoadInvokeParam<TestARequest>(guid); }
客端户执行方法格式
public void TestA(String guid) { var link = new LongInvokeLink<TestARequest, TestAResponse, IKX_InvokeService>(); try { var callParam= link.Begin(guid); link.P(string.Format("收到Name:{0},Items.Count:{1}", callParam.Name, callParam.Items.Count),10); Thread.Sleep(1000 * 2); link.P("执行一些费劲的操作..."); Thread.Sleep(1000 * 3); link.P(80); link.P("要返回了..."); Thread.Sleep(1000 * 2); #region 构建方法返回 var rModle = new TestAResponse() { Id = 2, Name = "张士大夫" };//执行结果 rModle.Items = new List<string>(); for (int i = 0; i < 100; i++) { rModle.Items.Add("第Item" + i); } #endregion link.Complete4Success(rModle); } catch (Exception ex) { link.Complete4Fail(ex.Message); } }
执行方法需要定义在反射能获取到的类型里
const String C_KXKey = "-KXInvoke:"; const String C_KXKey2 = "-KXInvoke2:"; /// <summary> /// 对应SimpleMsgClientHandle /// 如果开头是$KXInvoke: /// 那么使用本扩展 /// 格式 $KXInvoke:方法名,参数1,参数2... /// </summary> /// <param name="msg"></param> private bool MsgHandleExtension(string msg) { try { var argTypes = new List<Type>(); var methodName = ""; var args = new List<Object>(); if (msg.StartsWith(C_KXKey)) { #region 模式A var arr = msg.Substring(C_KXKey.Length).Split("$".ToCharArray()); var invokeId = 0L; if (arr.Length >= 2) { invokeId = long.Parse(arr[0]); methodName = arr[1]; args.Add(invokeId); } argTypes.Add(typeof(long)); for (int i = 2; i < arr.Length; i++) { args.Add(arr[i]); argTypes.Add(typeof(String)); } #endregion } else if (msg.StartsWith(C_KXKey2)) { #region 模式A var arr = msg.Substring(C_KXKey2.Length).Split("$".ToCharArray()); var guid = ""; if (arr.Length >= 2) { guid = arr[0].Trim(); methodName = arr[1]; args.Add(guid); } argTypes.Add(typeof(String)); for (int i = 2; i < arr.Length; i++) { args.Add(arr[i]); argTypes.Add(typeof(String)); } #endregion } #region 执行反射调用 var method = this.GetType().GetMethod(methodName, argTypes.ToArray()); if (method != null) { if (args.Count <= 0) { method.Invoke(this, null); //单线程同步处理 } else { method.Invoke(this, args.ToArray()); } } else { Console.WriteLine("没有Public签名的方法:" + methodName); } #endregion } catch (Exception ex) { Console.WriteLine(ex.Message); } return true; }
原文:https://www.cnblogs.com/wdfrog/p/14646922.html