Beispiel #1
0
        /// <summary>
        /// 短信发送
        /// </summary>
        /// <param name="tel"></param>
        /// <param name="content"></param>
        /// <param name="res"></param>
        /// <returns></returns>
        public LocalErrCode SendMsg(string tel, string content, out CMPP_SUBMIT_RESP res, string spNumber = null)
        {
            if (spNumber == null)
            {
                spNumber = spPhoneNumber;
            }

            CMPP_SUBMIT[] subMsg = CreateSubmitMsg(serviceId, spId, spNumber, tel, content);
            //服务器响应
            CMPPMsgBody_Base resp     = null;
            LocalErrCode     localRes = LocalErrCode.组件未启动;

            res = null;
            for (int i = 0; i < subMsg.Length; i++)
            {
                localRes = clien.Submit(subMsg[i], out resp);
                res      = resp as CMPP_SUBMIT_RESP;
                if (localRes != LocalErrCode.成功 || res.Result != DeliverResult.正确)
                {
                    break;
                }
            }
            return(localRes);
        }
Beispiel #2
0
        public LocalErrCode Submit(CMPPMsgBody_Base sendMsg, bool waitResp = false)
        {
            CMPPMsgBody_Base result = null;

            return(Submit(sendMsg, out result, waitResp));
        }
Beispiel #3
0
        /// <summary>
        /// 发送消息(同步等待服务器响应)
        /// (0命令成功处理 -1组件未启动 -2通道不可用 -3生成下发数据时错误 -4命令超时 -5指令异常丢失 -6重复的命令序列号 -7返回值类型非期望)
        /// </summary>
        /// <returns>返回值errorCode</returns>
        public LocalErrCode Submit(CMPPMsgBody_Base sendMsg, out CMPPMsgBody_Base resp, bool waitResp = true)
        {
            int      currentChannelSN = channelSN; //记录当前通道序列号
            DateTime cmdSendTime;                  //处理命令超时

            resp = null;                           //响应

            if (waitResp)
            {
                //等待命令响应锁
                if (!System.Threading.Monitor.TryEnter(waitRespLock, MaxTimeOut * 1000))
                {
                    return(LocalErrCode.命令超时);
                }
                //添加命令队列
                if (!CmppCmdQueue.TryAdd(sendMsg.MyHead.Sequence_Id, null))
                {
                    return(LocalErrCode.重复的命令序列号);//重复的命令序列号
                }
            }

            cmdSendTime = DateTime.Now;

            //组件未启动,不能处理操作指令
            if (!runFlag)
            {
                return(LocalErrCode.组件未启动);
            }

            //判断通道是否可用,不可用进行绑定
            if (!channelStateReady)
            {
                Bind();
            }
            //false通道未建立 true通道已建立可以发送数据
            if (!channelStateReady)
            {
                return(LocalErrCode.通道不可用);//通道不可用
            }
            //信道建立 开心进行初始短信信息
            byte[] data;
            //填充
            data = sendMsg.WriteBytes();
            //进行发送,然后判断是否有返回值
            try
            {
                lock (channelLockFlag)
                {
                    currentChannelSN = channelSN;
                    client_sk.GetStream().Write(data, 0, data.Length);
                }
            }
            catch (Exception ex)
            {
                //写入操作失败,通道作废 移除命令
                //
                CloseSoket();
                WriteLog(ex.Message);
                if (waitResp)
                {
                    CmppCmdQueue.TryRemove(sendMsg.MyHead.Sequence_Id, out resp);
                }
                return(LocalErrCode.通道不可用);
            }
            channelLastUpdate = DateTime.Now;


            if (waitResp)
            {
                LocalErrCode result = WaiteResp(cmdSendTime, currentChannelSN, (uint)sendMsg.MyHead.Command_Id, sendMsg.MyHead.Sequence_Id, out resp);
                Monitor.Exit(waitRespLock);
                return(result);//
            }

            return(LocalErrCode.成功);
        }
Beispiel #4
0
        /// <summary>
        /// 等待响应
        /// (循环取命令队列)
        /// </summary>
        /// <param name="cmdSendTime"></param>
        /// <param name="currentChannelSN"></param>
        /// <param name="cmdId"></param>
        /// <param name="cmdSequence"></param>
        /// <param name="resp"></param>
        /// <returns></returns>
        private LocalErrCode WaiteResp(DateTime cmdSendTime, int currentChannelSN, uint cmdId, uint cmdSequence, out CMPPMsgBody_Base resp)
        {
            //判断命令超时情况,判断通道序列号变更情况,判断命令存活情况
            resp = null;
            do
            {
                //判断记录当前通道序列号 不等于构建通道的序列号 &&  当前信道是否建立成功
                if (currentChannelSN != channelSN && channelStateReady)
                {
                    return(LocalErrCode.等待响应时通道已改变);

                    break;
                }
                //CMPPMsgBody_Base tmp;
                //验证当前队列中是否含有序列号
                if (!CmppCmdQueue.TryGetValue(cmdSequence, out resp))
                {
                    return(LocalErrCode.指令异常丢失);//指令异常丢失

                    break;
                }
                if (resp != null)
                {
                    //判断是否为期望的返回值
                    if (((uint)resp.MyHead.Command_Id & 0x7fffffffU) == cmdId)
                    {
                        CmppCmdQueue.TryRemove(cmdSequence, out resp);
                        return(LocalErrCode.成功);
                    }
                    else
                    {
                        return(LocalErrCode.返回值类型非期望);//返回值类型非期望
                    }
                    //break;
                }
                Thread.Sleep(15);//每次进行15毫秒休眠
            }
            //验证是否在期望时间内返回数据
            while (cmdSendTime.AddSeconds(MaxTimeOut) > DateTime.Now && runFlag);

            return(LocalErrCode.命令超时);
        }
Beispiel #5
0
        /// <summary>
        /// 读取失败或无可读数据返回 null
        /// </summary>
        /// <returns></returns>
        private CMPPMsgBody_Base read()
        {
            byte[] buffer;
            try
            {
                //判断是否有可用的数据
                if (channelStateReady && client_sk != null && client_sk.Available > 0)
                {
                    buffer = readBuffer(client_sk.GetStream());
                }
                else
                {
                    return(null);//没有可供读取的数据
                }
                //将读取到的数据构建成对象
                CMPPMsgHeader head;

                //读出头部,判断命令类型
                head = CMPPMsgHeader.Read(buffer);
                //根据指令类型,构建应答对象,对于不处理的指令进行丢弃
                CMPPMsgBody_Base data = null;
                switch (head.Command_Id)
                {
                case Command_Id.CMPP_SUBMIT_RESP:
                    data = new CMPP_SUBMIT_RESP(head.Sequence_Id);
                    break;

                case Command_Id.CMPP_DELIVER:
                    data = new CMPP_DELIVER(head.Sequence_Id);
                    break;

                case Command_Id.CMPP_ACTIVE_TEST:
                    data = new CMPP_ACTIVE_TEST(head.Sequence_Id);
                    break;

                case Command_Id.CMPP_ACTIVE_TEST_RESP:
                    data = new CMPP_ACTIVE_TEST_RESP(head.Sequence_Id);
                    break;

                case Command_Id.CMPP_TERMINATE:
                    data = new CMPP_TERMINATE(head.Sequence_Id);
                    break;

                case Command_Id.CMPP_TERMINATERESP:
                    data = new CMPP_TERMINATE_RESP(head.Sequence_Id);
                    break;

                default:
                    break;
                }
                if (data != null)
                {
                    data.ReadBytes(buffer);
                }
                return(data);
            }
            catch (Exception)//流读取异常
            {
                CloseSoket();
                return(null);
            }
        }
Beispiel #6
0
        /// <summary>
        /// 后台读取线程
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void bWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker bw = sender as BackgroundWorker;

            //处理过程
            while (!bw.CancellationPending)
            {
                //判断通道是否可用
                if (channelStateReady)
                {
                    //从通道中读取数据对象,若返回值为null 则表示无数据或读取出错(读取出错处理在 read方法进行处理)
                    CMPPMsgBody_Base data = read();
                    if (data != null)
                    {
                        channelLastUpdate = DateTime.Now;
                        //对读取到的数据进行处理
                        switch (data.MyHead.Command_Id)
                        {
                            #region 命令响应
                        case Command_Id.CMPP_SUBMIT_RESP:
                        case Command_Id.CMPP_ACTIVE_TEST_RESP:
                            if (CmppCmdQueue.ContainsKey(data.MyHead.Sequence_Id))
                            {
                                CmppCmdQueue[data.MyHead.Sequence_Id] = data;
                            }
                            break;

                            #endregion
                            #region 状态回报 上行
                        case Command_Id.CMPP_DELIVER:
                            ThreadPool.QueueUserWorkItem(ThreadPoolExcuteFuctione, data);
                            //响应服务器
                            CMPP_DELIVER      deliver     = data as CMPP_DELIVER;
                            CMPP_DELIVER_RESP deliverResp =
                                new CMPP_DELIVER_RESP(deliver.MyHead.Sequence_Id, deliver.Msg_Id, (uint)DeliverResult.正确);
                            Submit(deliverResp);
                            break;

                            #endregion
                            #region 拆除连接
                        case Command_Id.CMPP_TERMINATE:
                            Submit(new CMPP_TERMINATE_RESP(data.MyHead.Sequence_Id));
                            CloseSoket();
                            break;

                            #endregion
                            #region 连接检测
                        case Command_Id.CMPP_ACTIVE_TEST:
                            Submit(new CMPP_ACTIVE_TEST_RESP(data.MyHead.Sequence_Id));
                            break;

                            #endregion
                        default:    //未知的命令丢弃
                            break;
                        }
                    }
                }
                //判断通道空闲时间间隔,进行超时处理
                if (channelLastUpdate.AddSeconds(ActiveTestInterval) < DateTime.Now)
                {
                    var err = Submit(new CMPP_ACTIVE_TEST());//
                    if (err != LocalErrCode.成功)
                    {
                        channelLastUpdate = channelLastUpdate.AddSeconds(ActiveTestInterval);//n秒后重试 防止过多发送
                        WriteLog("长连接链路检测发送失败:" + err.ToString());
                    }
                }
                Thread.Sleep(10);//每个周期休眠10毫秒
            }
        }