示例#1
0
        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);
        }
示例#2
0
        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);
        }
示例#3
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));
        }
示例#4
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();
                }
            }
        }
        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();
                }
            }
        }