Ejemplo n.º 1
0
        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));
        }
Ejemplo n.º 2
0
        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();
                }
            }
        }
        protected internal void init()
        {
            initClientR();
            initClientS();

            this.Srv(Global.DC_CTRL_PING, (ping, pong) =>
            {
                return(Global.DC_CTRL_ACK);
            });

            mngThread = new Thread(new ThreadStart(delegate()
            {
                while (!disposed)
                {
                    try
                    {
                        Thread.Sleep(8000);
                        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);
                            this.Act(Global.DC_DIR_CLTSRVINFO_RPT, Global.DC_DIR_SRVID, data, 5);
                        }
                    }
                    catch (ThreadInterruptedException)
                    {
                        break;
                    }
                    catch (TimeoutException)
                    {
                        DCLogger.LogError("Report client status failed.");
                    }
                    catch (Exception ex)
                    {
                        DCLogger.LogError("Report detect a unhandled error:{0}", ex.Message);
                    }

                    //try
                    //{
                    //    Thread.Sleep(8000);
                    //    this.Act(Global.DC_CTRL_PING, this.id, new byte[0], 3);
                    //    //DCLogger.LogInfo("Connection onlined.");
                    //}
                    //catch (ThreadInterruptedException)
                    //{
                    //    break;
                    //}
                    //catch (TimeoutException)
                    //{
                    //    DCLogger.LogError("Connection broked.");
                    //    bool reconn = false;
                    //    int retry = 0;
                    //    while (!reconn)
                    //    {
                    //        if (clientR == null || clientRThread == null || !clientRThread.IsAlive)
                    //        {
                    //            clientRThread = null;
                    //            clientR = null;
                    //            initClientR();
                    //            //DCLogger.LogInfo("ClientR reloaded.");
                    //        }
                    //        else
                    //        {
                    //            string[] addrs = cfg.ServerS.Split(',');
                    //            foreach (string addr in addrs)
                    //            {
                    //                clientR.Connect(addr);
                    //            }
                    //        }

                    //        try
                    //        {
                    //            DCLogger.LogInfo("Reconnect retry {0}.", ++retry);
                    //            this.Act(Global.DC_CTRL_PING, this.id, new byte[0], 3);
                    //            reconn = true;
                    //            DCLogger.LogInfo("Connection reonlined.");
                    //        }
                    //        catch (TimeoutException)
                    //        {
                    //            continue;
                    //        }
                    //    }
                    //}
                    //catch (Exception ex)
                    //{
                    //    DCLogger.LogError("Connect detect a unhandled error:{0}", ex.Message);
                    //}
                }
            }
                                                   ));
            mngThread.IsBackground = true;
            mngThread.Start();
        }