Пример #1
0
        private TranMsg CombineMsg(TranMsgType type)
        {
            var     queue = this._msgQueue[type];
            TranMsg ms    = TranMsg.Combine(queue.ToArray());

            queue.Clear();
            return(ms);
        }
Пример #2
0
        public void OnDataReceived(IDtuConnection c, DtuMsg msg)
        {
            if (msg == null)
            {
                Log.ErrorFormat("Received a null msg from {0}.", c);
                return;
            }

            if (!msg.IsOK())
            {
                Log.DebugFormat("Invalid Msg, dropped.");
                return;
            }
            TranMsg tm = new TranMsg(msg.Databuffer);
            // Send ack.
            TranMsg ack = new HeartBeatTranMsg(Convert.ToInt32(msg.DtuId), tm.LoadSize); // ACK

            ack.ID = tm.ID;                                                              // SAME.

            c.Asend(ack.Marshall());
            if (TranMsgType.HeartBeat == tm.Type)
            {
                // HeartBeat.
                Log.DebugFormat("heartBeat, send ack and continue");
                return;
            }
            Log.DebugFormat("OnDataReceived: id={4},result={0}, len={1}, pkg={2}/{3}", msg.ErrorCode,
                            msg.Databuffer != null ? msg.Databuffer.Length : 0, tm.PackageIndex, tm.PackageCount, tm.ID);
            if (!tm.IsLastPackage())
            {
                // 入列.
                this.EnqueueMsg(tm);
                return;
            }
            // 最后一包已到达, 或仅一包.
            TranMsg outMsg = null;

            if (tm.PackageCount > 1)
            {
                Log.DebugFormat("Last package, combine them.");
                outMsg = this.CombineMsg(tm.Type); //组包
            }
            else
            {
                outMsg = tm; //单包.
            }
            // 委托调用.
            if (this.OnTranMsgReceived != null)
            {
                this.OnTranMsgReceived(tm.Type, outMsg);
            }
        }
Пример #3
0
        public bool SSend(TranMsg req, int timeout, out TranAckMsg resp)
        {
            DtuMsg msg = this._dtuConnection.Ssend(req.Marshall(), timeout);

            resp = new TranAckMsg();
            if (msg.IsOK())
            {
                resp.Unmarshall(msg.Databuffer);
                return(true);
            }
            else
            {
                resp.ErrorMsg  = msg.ErrorMsg;
                resp.ErrorCode = msg.ErrorCode;
                return(false);
            }
        }
Пример #4
0
        private void EnqueueMsg(TranMsg tm)
        {
            TranMsgType     t     = tm.Type;
            Queue <TranMsg> queue = null;

            if (!this._msgQueue.ContainsKey(t))
            {
                this._msgQueue[t] = queue = new Queue <TranMsg>();
            }
            else
            {
                queue = this._msgQueue[t];
                if (tm.PackageIndex == 0 && queue.Count > 0)
                {
                    Log.ErrorFormat("Invalid msg idx: {0}, purge old packages.", tm.PackageIndex);
                    queue.Clear();
                }
            }
            queue.Enqueue(tm);
        }
Пример #5
0
        public static TranMsg Combine(TranMsg[] msgs)
        {
            TranMsg msg = new TranMsg();
            int     len = 0;

            foreach (TranMsg tm in msgs)
            {
                len += tm.LoadSize;
            }
            msg.Data         = new byte[len];
            msg.PackageIndex = 0;
            msg.PackageCount = 1;
            msg.LoadSize     = (ushort)len;
            int offset = 0;

            foreach (TranMsg tm in msgs)
            {
                Array.Copy(tm.Data, 0, msg.Data, offset, tm.LoadSize);
                offset += tm.LoadSize;
            }
            return(msg);
        }
Пример #6
0
 private void _run()
 {
     while (!this._source.IsCancellationRequested)
     {
         if (!this._delegator.IsConnected())
         {
             Log.InfoFormat("Reconnecting to delegate");
             this._delegator.Connect();
             Thread.Sleep(200);
             if (!this._delegator.IsConnected())
             {
                 Log.InfoFormat("Connecting error, retry after 1 second.");
                 Thread.Sleep(1000);
                 continue;
             }
             else
             {
                 Log.InfoFormat("Connected.");
             }
         }
         foreach (ITranDataProvider _provider in this._providers)
         {
             if (this._source.IsCancellationRequested)
             {
                 break;
             }
             if (_provider.HasMoreData()) //未发送完毕
             {
                 if (this._source.IsCancellationRequested)
                 {
                     break;
                 }
                 int       len        = 0;
                 TranMsg[] msgs       = _provider.NextPackages(out len);
                 int       sendingIdx = 0;
                 bool      allMsgSent = false;
                 long      started    = System.DateTime.Now.Ticks;
                 while (sendingIdx < msgs.Length) // 循环发送
                 {
                     if (this._source.IsCancellationRequested)
                     {
                         break;
                     }
                     TranMsg m = msgs[sendingIdx];
                     Log.DebugFormat("Sending package: {0}: {1}/{2}, len={3}", m.ID, sendingIdx, msgs.Length, m.LoadSize);
                     try
                     {
                         TranAckMsg ack;
                         if (this._delegator.SSend(m, DTU_SEND_TIMEOUT, out ack))
                         {
                             if (!this.IsValidAck(m, ack))
                             {
                                 {
                                     Log.ErrorFormat("Sent failed, ack error, {0}!={1}", m.LoadSize, ack.Received);
                                     continue; // resent it.
                                 }
                             }
                             sendingIdx++; //发送成功.
                             if (this.OnMessageSent != null)
                             {
                                 this.OnMessageSent.Invoke(m, ack); //异步
                             }
                             allMsgSent = sendingIdx == msgs.Length;
                             Thread.Sleep(100);
                         }
                         else
                         {
                             Log.ErrorFormat("Sending error: {0}, retry after 2 second: ", ack.ErrorMsg);
                             Thread.Sleep(1000);
                         }
                     }
                     catch (Exception e)
                     {
                         Log.ErrorFormat("Sending exception: {0}: ", e.Message);
                         Thread.Sleep(1000);
                     }
                 }
                 if (allMsgSent)
                 {
                     Log.DebugFormat("Package Group sent in {0} seconds.",
                                     (System.DateTime.Now.Ticks - started) / 10000);
                     _provider.OnPackageSent();
                 }
                 Thread.Sleep(10);
             }
             else
             {
                 Log.InfoFormat("No more data. wait {0} seconds.", NO_DATA_WAIT_SECONDS);
                 Thread.Sleep(NO_DATA_WAIT_SECONDS * 1000);
             }
         }
     }
 }
Пример #7
0
 private bool IsValidAck(TranMsg req, TranAckMsg resp)
 {
     return(resp.Received == req.LoadSize || resp.ID != req.ID);
 }