Exemplo n.º 1
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();
                }
            }
        }