public override ActResult Act(string type, byte[] data, int timeoutSeconds) { if (timeoutSeconds < 1) { throw new ArgumentException("Illegal timeoutSeconds.", "timeoutSeconds"); } ActResult ret = null; this.Act(type, data, (a) => { ret = a; }); int waitTimes = 0; while (ret == null && waitTimes++ < (timeoutSeconds * 10)) { Thread.Sleep(100); } if (ret == null) { throw new TimeoutException(string.Format("Act {0} time out.", type)); } if (ret.Exception != null) { throw ret.Exception; } return(ret); }
public override ActResult Act(string type, byte[] data) { ActResult ret = null; this.Act(type, data, (a) => { ret = a; }); int waitTimes = 0; while (ret == null && waitTimes++ < 50) { Thread.Sleep(100); } if (ret == null) { throw new TimeoutException(string.Format("Act {0} time out.", type)); } if (ret.Exception != null) { throw ret.Exception; } return(ret); }
public override int Act(string type, byte[] data, Action <ActResult> handler) { string baseType = type; int idx = baseType.IndexOf('?'); if (idx > 0) { baseType = baseType.Substring(0, idx); } List <StringAndTime> srvId = null; if (type2Srv.TryGetValue(baseType, out srvId)) { //DCLogger.LogTrace("srvId.Count = {0}", srvId.Count); srvId.RemoveAll((item) => { //DCLogger.LogTrace("DateTime.Now.Ticks - item.LastRefresh = {0}", DateTime.Now.Ticks - item.LastRefresh); return((DateTime.Now.Ticks - item.LastRefresh) > (60 * 10000000)); }); } //if (type2Srv.ContainsKey(baseType)) //{ // srvId = type2Srv[baseType]; // srvId.RemoveAll((item) => { return (DateTime.Now.Ticks - item.LastRefresh) > (30 * 1000); }); //} if (srvId == null || srvId.Count == 0) { ActResult ar = this.Act(Global.DC_DIR_CLTSRVINFO_QRY, Global.DC_DIR_SRVID, Global.Encoding.GetBytes(baseType)); DCLogger.LogTrace("Query available srv of type [{0}]", baseType); if (ar.ResultData.Length > 0) { srvId = DCSerializer.BytesToObj <List <StringAndTime> >(ar.ResultData); type2Srv.AddOrUpdate(baseType, srvId, (key, oldValue) => srvId); //if (type2Srv.ContainsKey(baseType)) //{ // type2Srv[baseType] = srvId; //} //else //{ // type2Srv.Add(baseType, srvId); //} } else { throw new MissingMethodException(string.Format("No one announce to service {0}", baseType)); } } return(this.Act(type, srvId[new Random().Next(0, srvId.Count)].UniqueString, data, handler)); }
private void initClientR() { poller = new Poller(); { //clientR = context.CreateSubscriberSocket(); //clientS = context.CreatePushSocket(); { try { createRSocket(); createSSocket(); } catch (Exception ex) { DCLogger.LogError("Exception in connect work:{0}", ex.Message); } //r & s clientR.ReceiveReady += (sender, eventArgs) => { try { List <byte[]> dataLst = new List <byte[]>(); clientR.ReceiveMultipartBytes(ref dataLst, 2); //if (dataLst.Count != 2) // return; byte[] envelope = dataLst[0]; byte[] data = dataLst[1]; //if (envelope == null) // return; if (DCUtil.BytesStart(Global.DC_CTRL_HB, envelope)) { lastTicksOfHb = BitConverter.ToInt64(data, 0); DCLogger.LogInfo("Server's HeartBeat received: {0}", new DateTime(lastTicksOfHb)); } #region pubDataR 处理Sub接口订阅的数据 else if (DCUtil.BytesStart(Global.DC_HEAD_PS_PUB_BYTES, envelope)) { string envelopeStr = Global.Encoding.GetString(envelope); string envelopeStr0 = string.Concat(Global.DC_HEAD_PS_PUB, Global.ENVELOPE_SPLITTER, envelopeStr.Split(new string[] { Global.ENVELOPE_SPLITTER }, StringSplitOptions.None)[1]); //Console.WriteLine("keys:" + string.Concat(clientRHands.Keys) + "_key:" + envelopeStr); ConcurrentDictionary <Action <byte[]>, object> actions; bool envelopeStrBingo = false; if (subHands.TryGetValue(envelopeStr, out actions)) { envelopeStrBingo = true; foreach (Action <byte[]> handler in actions.Keys) { if (handler != null) { handler(data); } } } if (!envelopeStrBingo) { if (subHands.TryGetValue(envelopeStr0, out actions)) { foreach (Action <byte[]> handler in actions.Keys) { if (handler != null) { try { handler(data); } catch (Exception ex) { DCLogger.LogError("Exception occured when handling pub's data:{0}", ex.Message); } } } } } } #endregion #region actDataR 处理Srv接口接收的Act请求 else if (DCUtil.BytesStart(Global.DC_HEAD_AS_ACT_BYTES, envelope)) { string envelopeStr = Global.Encoding.GetString(envelope); string[] actDetail = envelopeStr.Split(new string[] { Global.ENVELOPE_SPLITTER }, StringSplitOptions.None); if (srvTypes.ContainsKey(actDetail[1 + 1])) { Thread inlineThread = new Thread(new ThreadStart(delegate() { byte[] actResultData = null; string replySn = "0"; string extInfo = string.Empty; string lastSlice = actDetail[actDetail.Length - 1]; try { replySn = actDetail[1 + 3]; int idx = lastSlice.IndexOf("?"); if (idx > 0) { extInfo = lastSlice.Substring(idx + 1); } actResultData = srvTypes[actDetail[1 + 1]](extInfo, data); } catch (Exception ex) { string srvSideException = string.Format("Srv side exception [{0}][{1}]: ", id, actDetail[1 + 1]) + ex.Message; actResultData = Global.Encoding.GetBytes(Global.Encoding.GetString(Global.DC_RPLY_EXCEPTION) + srvSideException); DCLogger.LogError(srvSideException); } if (actResultData == null) { actResultData = Global.DC_NULL_RPLY; } lock (clientSSync) { try { clientS.SendMultipartBytes(Global.Encoding.GetBytes(string.Concat(Global.DC_HEAD_AS_RPLY, Global.ENVELOPE_SPLITTER, actDetail[1 + 2], Global.ENVELOPE_SPLITTER, actDetail[1 + 1], Global.ENVELOPE_SPLITTER, id, Global.ENVELOPE_SPLITTER, replySn)), actResultData); } catch (Exception ex) { DCLogger.LogError("Exception occured when srv sending reply data back:{0}", ex.Message); } } } )); inlineThread.IsBackground = true; inlineThread.Start(); } } #endregion #region srvRplyDataR 处理Act请求的Srv Reply else if (DCUtil.BytesStart(Global.DC_HEAD_AS_RPLY_BYTES, envelope)) { string envelopeStr = Global.Encoding.GetString(envelope); if (DCUtil.BytesEqual(Global.DC_NULL_RPLY, data)) { data = null; } string[] replyDetail = envelopeStr.Split(new string[] { Global.ENVELOPE_SPLITTER }, StringSplitOptions.None); int snKey = int.Parse(replyDetail[1 + 3]); System.Diagnostics.Debug.WriteLine("ActResult received [{0}]", snKey); Action <ActResult> handler; if (actResultHands.TryGetValue(snKey, out handler)) { ActResult ar = new ActResult { ResultData = data, Type = replyDetail[1 + 1], Src = replyDetail[1 + 2], ActSn = int.Parse(replyDetail[1 + 3]) }; actResultHands.TryRemove(snKey, out handler); System.Diagnostics.Debug.WriteLine("Act Key removed [{0}]", snKey); if (DCUtil.BytesStart(Global.DC_RPLY_EXCEPTION, ar.ResultData)) { ar.Exception = new Exception(Global.Encoding.GetString(ar.ResultData, Global.DC_RPLY_EXCEPTION.Length, ar.ResultData.Length - Global.DC_RPLY_EXCEPTION.Length)); } try { //Task.Factory.StartNew(() =>handler(ar)); ThreadPool.QueueUserWorkItem(o => { ActResult ar_real = ar as ActResult; handler(ar_real); }, ar); } catch (Exception ex) { DCLogger.LogError("Exception occured when act handling srv's reply data:{0}", ex.Message); } StringAndTime tnt = new StringAndTime { UniqueString = ar.Src, LastRefresh = DateTime.Now.Ticks }; type2Srv.AddOrUpdate( ar.Type, new List <StringAndTime>(), (key, oldValue) => { if (oldValue.Contains(tnt)) { oldValue[oldValue.IndexOf(tnt)].LastRefresh = DateTime.Now.Ticks; } else { oldValue.Add(tnt); //Console.WriteLine("List<TypeAndTime>.Count: {0}", oldValue.Count); } //DCLogger.LogTrace("Refresh valid datetime of srv [{0}] type [{1}]", ar.Src, ar.Type); return(oldValue); } ); } } #endregion #region sndDataR 处理Rcv接口接受的数据 else if (DCUtil.BytesStart(Global.DC_HEAD_SR_SND_BYTES, envelope)) { string envelopeStr = Global.Encoding.GetString(envelope); ConcurrentDictionary <Action <byte[]>, object> actions; if (rcvHands.TryGetValue(envelopeStr, out actions)) { foreach (Action <byte[]> handler in actions.Keys) { if (handler != null) { try { handler(data); } catch (Exception ex) { DCLogger.LogError("Exception occured when rcv handling snd's data:{0}", ex.Message); } } } } } #endregion } catch (Exception ex) { DCLogger.LogError("Exception in receive data proc work:{0}", ex.Message); } }; poller.AddSocket(clientR); // send report every 8 seconds NetMQTimer heartbeatTimer = new NetMQTimer(5000); poller.AddTimer(heartbeatTimer); heartbeatTimer.Elapsed += (sender, eventArgs) => { try { if (lastTicksOfHb > 0 && (DateTime.Now.Ticks - lastTicksOfHb) > (38 * 10000000)) { DCLogger.LogError("Server's connection losed"); reconnect(); //new System.Threading.Tasks.Task(() => reconnect()).Start(); } IEnumerator <string> itor = this.srvTypes.Keys.GetEnumerator(); List <CltSrvInfo> srvInfos = new List <CltSrvInfo>(); while (itor.MoveNext()) { if (!itor.Current.Equals(Global.DC_CTRL_PING)) { srvInfos.Add(new CltSrvInfo { ClientId = this.id, ClientSrvType = itor.Current }); } } if (srvInfos.Count > 0) { byte[] data = DCSerializer.ObjToBytes(srvInfos); Task.Factory.StartNew(() => this.Act(Global.DC_DIR_CLTSRVINFO_RPT, Global.DC_DIR_SRVID, data, 5) ); DCLogger.LogInfo("Report client status ok."); } } catch (TimeoutException) { DCLogger.LogError("Report client status failed."); } catch (Exception ex) { DCLogger.LogError("Report detect a unhandled error:{0}", ex.Message); } }; poller.PollTillCancelled(); } } }
private void initClientR() { if (clientR != null) { return; } lock (clientRSync) { if (clientR != null) { return; } if (!string.IsNullOrEmpty(cfg.ServerS)) { createRSocket(); clientRThread = new Thread(new ThreadStart(delegate() { //byte[] buffer = new byte[8388608]; long lastTicksOfHb = 0; while (!disposed) { byte[] envelope; // = receiver.Receive(); byte[] data; // = receiver.Receive(); try { //clientR.Receive(out envelope, out data); clientR.TryReceive(1000, out envelope, out data); } catch (Exception ex) { DCLogger.LogError("clientR receive failed: {0}", ex.Message); continue; } //if (DCUtil.BytesEqual(guid, envelope) && DCUtil.BytesEqual(Global.DC_CTRL_EXIT, data)) //{ // break; //} if (envelope == null) { continue; } if (DCUtil.BytesEqual(Global.DC_CTRL_HB, envelope)) { lastTicksOfHb = BitConverter.ToInt64(data, 0); DCLogger.LogInfo("Server's HeartBeat received: {0}", new DateTime(lastTicksOfHb)); } if (lastTicksOfHb > 0 && (DateTime.Now.Ticks - lastTicksOfHb) > (15 * 10000000)) { DCLogger.LogError("Server's connection losed"); reconnect(); //new System.Threading.Tasks.Task(() => reconnect()).Start(); } #region pubDataR 处理Sub接口订阅的数据 if (DCUtil.BytesStart(Global.DC_HEAD_PS_PUB_BYTES, envelope)) { string envelopeStr = Global.Encoding.GetString(envelope); string envelopeStr0 = string.Concat(Global.DC_HEAD_PS_PUB, Global.ENVELOPE_SPLITTER, envelopeStr.Split(new string[] { Global.ENVELOPE_SPLITTER }, StringSplitOptions.None)[1]); //Console.WriteLine("keys:" + string.Concat(clientRHands.Keys) + "_key:" + envelopeStr); ConcurrentDictionary <Action <byte[]>, object> actions; bool envelopeStrBingo = false; if (subHands.TryGetValue(envelopeStr, out actions)) { envelopeStrBingo = true; foreach (Action <byte[]> handler in actions.Keys) { if (handler != null) { handler(data); } } } if (!envelopeStrBingo) { if (subHands.TryGetValue(envelopeStr0, out actions)) { foreach (Action <byte[]> handler in actions.Keys) { if (handler != null) { try { handler(data); } catch (Exception ex) { DCLogger.LogError("Exception occured when handling pub's data:{0}", ex.Message); } } } } } } #endregion #region actDataR 处理Srv接口接收的Act请求 else if (DCUtil.BytesStart(Global.DC_HEAD_AS_ACT_BYTES, envelope)) { string envelopeStr = Global.Encoding.GetString(envelope); string[] actDetail = envelopeStr.Split(new string[] { Global.ENVELOPE_SPLITTER }, StringSplitOptions.None); if (srvTypes.ContainsKey(actDetail[1 + 1])) { Thread inlineThread = new Thread(new ThreadStart(delegate() { byte[] actResultData = null; string replySn = "0"; string extInfo = string.Empty; string lastSlice = actDetail[actDetail.Length - 1]; try { replySn = actDetail[1 + 3]; int idx = lastSlice.IndexOf("?"); if (idx > 0) { extInfo = lastSlice.Substring(idx + 1); } actResultData = srvTypes[actDetail[1 + 1]](extInfo, data); } catch (Exception ex) { string srvSideException = string.Format("Srv side exception [{0}][{1}]: ", id, actDetail[1 + 1]) + ex.Message; actResultData = Global.Encoding.GetBytes(Global.Encoding.GetString(Global.DC_RPLY_EXCEPTION) + srvSideException); DCLogger.LogError(srvSideException); } if (actResultData == null) { actResultData = Global.DC_NULL_RPLY; } lock (clientSSync) { try { clientS.Send(Global.Encoding.GetBytes(string.Concat(Global.DC_HEAD_AS_RPLY, Global.ENVELOPE_SPLITTER, actDetail[1 + 2], Global.ENVELOPE_SPLITTER, actDetail[1 + 1], Global.ENVELOPE_SPLITTER, id, Global.ENVELOPE_SPLITTER, replySn)), actResultData); } catch (Exception ex) { DCLogger.LogError("Exception occured when srv sending reply data back:{0}", ex.Message); } } } )); inlineThread.IsBackground = true; inlineThread.Start(); } } #endregion #region srvRplyDataR 处理Act请求的Srv Reply else if (DCUtil.BytesStart(Global.DC_HEAD_AS_RPLY_BYTES, envelope)) { string envelopeStr = Global.Encoding.GetString(envelope); if (DCUtil.BytesEqual(Global.DC_NULL_RPLY, data)) { data = null; } string[] replyDetail = envelopeStr.Split(new string[] { Global.ENVELOPE_SPLITTER }, StringSplitOptions.None); int snKey = int.Parse(replyDetail[1 + 3]); System.Diagnostics.Debug.WriteLine("ActResult received [{0}]", snKey); Action <ActResult> handler; if (actResultHands.TryGetValue(snKey, out handler)) { ActResult ar = new ActResult { ResultData = data, Type = replyDetail[1 + 1], Src = replyDetail[1 + 2], ActSn = int.Parse(replyDetail[1 + 3]) }; actResultHands.TryRemove(snKey, out handler); System.Diagnostics.Debug.WriteLine("Act Key removed [{0}]", snKey); if (DCUtil.BytesStart(Global.DC_RPLY_EXCEPTION, ar.ResultData)) { ar.Exception = new Exception(Global.Encoding.GetString(ar.ResultData, Global.DC_RPLY_EXCEPTION.Length, ar.ResultData.Length - Global.DC_RPLY_EXCEPTION.Length)); } try { handler(ar); } catch (Exception ex) { DCLogger.LogError("Exception occured when act handling srv's reply data:{0}", ex.Message); } StringAndTime tnt = new StringAndTime { UniqueString = ar.Src, LastRefresh = DateTime.Now.Ticks }; type2Srv.AddOrUpdate( ar.Type, new List <StringAndTime>(), (key, oldValue) => { if (oldValue.Contains(tnt)) { oldValue[oldValue.IndexOf(tnt)].LastRefresh = DateTime.Now.Ticks; } else { oldValue.Add(tnt); //Console.WriteLine("List<TypeAndTime>.Count: {0}", oldValue.Count); } //DCLogger.LogTrace("Refresh valid datetime of srv [{0}] type [{1}]", ar.Src, ar.Type); return(oldValue); } ); } } #endregion #region sndDataR 处理Rcv接口接受的数据 else if (DCUtil.BytesStart(Global.DC_HEAD_SR_SND_BYTES, envelope)) { string envelopeStr = Global.Encoding.GetString(envelope); ConcurrentDictionary <Action <byte[]>, object> actions; if (rcvHands.TryGetValue(envelopeStr, out actions)) { foreach (Action <byte[]> handler in actions.Keys) { if (handler != null) { try { handler(data); } catch (Exception ex) { DCLogger.LogError("Exception occured when rcv handling snd's data:{0}", ex.Message); } } } } } #endregion } } )); clientRThread.Priority = ThreadPriority.Highest; clientRThread.IsBackground = true; clientRThread.Start(); } } }