http 长连接 ++++++++++++++++++ 手动维持 长连接

长连接: 指在一个TCP连接上可以连续发送多个数据包,
        在TCP连接保持期间,如果没有数据包发送,需要双方发检测包以维持此连接;
        一般需要自己做在线维持。




            //http长连接的使用
            //m_pSimpleHttp =  new SimpleHttp(HTTP_KEEPALIVE,this);//长连接类型 的http请求------------------- NetWorkCommunication中创建一个SimpleHttp的实例
            //该m_pSimpleHttp维持 http长连接

            //普通http请求的使用,非长连接
            //NetworkCommunicate类中, m_pGetMsgHttp =  new SimpleHttp(HTTP_POST,this);
            
            //不管是长连接的http实例,还是非长连接的http实例,都是在NetWorkCommunication的析构函数中才会析构掉
            
            
            //长连接和其他链接,没什么区别,长连接是个httpManager对象,该对象和服务器进行链接,
            //服务器每隔15秒就向 该http链接中发送一个数据(心跳包), 客户端如果45s后,还没有收到 服务端发送过来的心跳包,那么客户端就主动关闭该http链接,
            //非长连接,45s后,直接关闭掉该http连接,
            

            enum HTTP_MODE
            {
                HTTP_GET = 0,
                HTTP_POST,
                HTTP_DOWNLOADFILE,
                HTTP_UPLOADFILE,
                HTTP_KEEPALIVE
            };//http请求的类型 get post downloadfile uploadfile等
            
            SimpleHttp* HttpRequestManage::addKeepAlivePost(TASK_PARAM * pTask)
            {
                KeepAliveTask* pKeepAliveTask = dynamic_cast<KeepAliveTask*>(pTask);
                if(!pKeepAliveTask)
                    return NULL;

                SimpleHttp* pHttp = new SimpleHttp(HTTP_KEEPALIVE, this);//标识 该请求为长连接请求---------------------
                pHttp->setOutTimer(pKeepAliveTask->m_OutTimer);
                pHttp->setPostRequestParam(pKeepAliveTask->m_strParam);
                pHttp->setRecvMsgFunc(pKeepAliveTask->m_RecvMsgFunc);
                pHttp->SetAtOnce(pKeepAliveTask->m_bAtOnce);
                pHttp->httpRequest(pKeepAliveTask->m_strUrl, pKeepAliveTask->m_CompleteFunc);

                return pHttp;
            }
            
            //开始做任务 执行http请求
            void SimpleHttp::startRequest()
            
                case HTTP_KEEPALIVE:
                {
                    connect(m_spHttp.data(), SIGNAL(finished(QNetworkReply*)), this, SLOT(httpFinished(QNetworkReply*)));
                    QNetworkRequest request(m_Url);
                    QByteArray param;
                    if(m_PostParam.isEmpty())
                        param = m_Url.encodedQuery();
                    else
                        param.append(m_PostParam);

                    if(!m_Headers.isEmpty())
                    {
                        for(int i=0; i<m_Headers.size(); ++i)
                        {
                            QPair<QNetworkRequest::KnownHeaders, QVariant> pair = m_Headers[i];
                            request.setHeader(pair.first, pair.second);
                        }
                    }
                    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
                    m_NetworkReply = m_spHttp->post(request, param);
                    connect(m_NetworkReply, SIGNAL(readyRead()), this, SLOT(OnRecvMsg()));//http请求 已经返回数据了------------------ 对获取到的长连接请求的返回数据进行处理
                    connect(m_NetworkReply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(httpError(QNetworkReply::NetworkError)));
                }
                if(m_OutTime < 0 && m_Mode == HTTP_KEEPALIVE )
                {
                    m_OutTime = HEARTBEAT_TIME;        //这个超时来处理心跳包
                    if(!m_AutoBreakOutTimer)
                    {
                        m_AutoBreakOutTimer = new QTimer(this);
                        connect(m_AutoBreakOutTimer, SIGNAL(timeout ()), this, SLOT(OnAutoBreakOutTimer()));
                    }
                    else
                    {
                        m_AutoBreakOutTimer->stop();
                    }

                    m_AutoBreakOutTimer->start(AUTO_BREAK_TIME);  //长连接使用
                }

                m_OutTimer->start(m_OutTime);
                
                
            

            //定时器的超时响应函数            
            /*
            服务端每隔15秒发一次心跳包
            //长连接请求发出后,该定时器设定为45秒后触发
            //下面槽的作用,就是为了检测m_bRecvHeartbeat的值,即客户端是否收到了服务端发过来的心跳包
            */
            void SimpleHttp::OnOutTimer()
            {
                //定时器超时了
                m_bOutTime = true;
                if(m_Mode != HTTP_KEEPALIVE)
                {

                    m_OutTimer->stop();


                     m_NetworkReply->close();    //非长连接 ,手动将该链接关闭,以免占用服务端的资源-------------------------------------长连接和短链接的根本的区别
                }
                else
                {
                    //http是长连接
                    //开始检查心跳包
                    // 因为服务器每隔15s就发送一次心跳包
                    //如果45s还没有收到心跳包,那么说明连接中断了,
                    if(!m_bRecvHeartbeat)  //心跳包停止了
                    {
                        m_OutTimer->stop();
                        m_AutoBreakOutTimer->stop();
                    
                         m_NetworkReply->close();//没有收到心跳包,关闭http连接     //-------------------------------------长连接和短链接的根本的区别
                    }
                    else
                    {
                        //接收到了服务端发过来的心跳包,那么不关闭http连接
                        m_bRecvHeartbeat = false;
                    }
                }
            }

            
                
                

//第一步
//网络连接 NetrokCommunicate类,使用的就是http长连接。
//只使用了这一中连接http连接方式。
            NetworkCommunicate::NetworkCommunicate(QObject *parent)
                : QObject(parent)
                , m_pSimpleHttp(NULL)
                , m_pGetMsgHttp(NULL)
                , m_Timer(NULL)
                , m_nRequestNum(0)
                , m_bPullMsg(true)
                , m_nRetryTimes(0)
            {
                    m_pSimpleHttp =  new SimpleHttp(HTTP_KEEPALIVE,this);//长连接类型 的http请求-------------
                    
                

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值