4-连接服务器

上篇使用python + tornado搭建了一个最简单的服务,现在我们在客户端连接下我们的服务器,实现clientserver的通信。


一,环境

OS X 10.8.5 XCode 5.1.1cocos2dx 2.1rc0-x-2.1.4


二,cocos2dxhttp请求

cocos2dx为我们提供了CCHttpRequestCCHttpClient(单例)两个类来发起http请求,使用方法如下:

       CCHttpRequest *pRequest = new CCHttpRequest();
       pRequest->setUrl("http://127.0.0.1");
       pRequest->setRequestType(CCHttpRequest::kHttpGet);
       pRequest->setResponseCallback(this, callfuncND_selector(HttpSender::HttpCallBack)); //设置回调
       CCHttpClient *pHttpClient = CCHttpClient::getInstance();
       pHttpClient->send(pRequest);

这样发起一次连接还马马虎虎能够接受,但是一个应用程序会有很多不同的请求,如果每个请求都按照上述方法进行,将会很繁琐,

代码将会很难维护。有必要对http请求进行再一次的封装。


三,对http请求进行封装

需求:简化发起http请求的代码量,使代码易维护;

设计:一个类(HttpSender)负责发起http请求、接收回调消息,将得到的消息传递给使用者(HttpCallbackTarget);

类图如下:


四,类HttpCallbackTarget的实现如下


/
//  CallbackTarget.h
//  MyClient_CPP
//
//  Created by Woodlouse on 14-9-3.
//
//

#ifndef __MyClient_CPP__HttpCallbackTarget__
#define __MyClient_CPP__HttpCallbackTarget__

//#include "CCObject.h"
#include "cocos2d.h"

namespace MyClient_CPP {

    class HttpCallbackTarget {
        
        public:
            //NVI
        void Callback(cocos2d::CCNode *pSrc, void *pData){
                GetData(pSrc, pData);
            }
        
        protected:
            HttpCallbackTarget(){};
            virtual ~HttpCallbackTarget(){};
        
            virtual void GetData(cocos2d::CCNode *pSrc, void *pData) = 0;
    };
}

#endif /* defined(__MyClient_CPP__CallbackTarget__) */

五,HttpSender类的实现如下


//
//  HttpSender.h
//  MyClient_CPP
//
//  Created on 14-9-3.
//
//  Functon : 发送http请求
//  Author : Woodlouse

#ifndef __MyClient_CPP__HttpSender__
#define __MyClient_CPP__HttpSender__

#include "HttpRequest.h"

using namespace cocos2d;
using namespace cocos2d::extension;

namespace MyClient_CPP{

    class HttpCallbackTarget;
    class HttpSender;
    
    class HttpSender : public CCObject{
        
    public:
        HttpSender(HttpCallbackTarget *pAgent);
        
        ~HttpSender(){
            CC_SAFE_RELEASE(m_pRequest);
        }
        
    public:
        //初始化信息
        void initRequest(const char *pUrl, CCHttpRequest::HttpRequestType type);
        void initRequest(const char *pUrl, CCHttpRequest::HttpRequestType type, const char *pData, int len);
        void send();
        
    private:
        CCHttpRequest* initRequest();
        //接收http回应得回调
        void HttpCallBack(CCNode *pRc, void *pData);
        
    private:
        CCHttpRequest *m_pRequest;
        //代理
        HttpCallbackTarget *m_pAgent;
    };
    
}

#endif /* defined(__MyClient_CPP__HttpSender__) */

.cpp如下:


//
//  HttpSender.cpp
//  MyClient_CPP
//
//  Created by Woodlouse on 14-9-3.
//
//

#include "HttpSender.h"
#include "HttpCallbackTarget.h"
#include "HttpClient.h"

using namespace MyClient_CPP;

HttpSender::HttpSender(HttpCallbackTarget *pAgent):
m_pRequest(NULL),
m_pAgent(NULL)
{
    if(!pAgent) {
        CCAssert(false, "Got an bad Agent");
        return;
    }
    
    m_pAgent = pAgent;
}

CCHttpRequest* HttpSender::initRequest()
{
    if (m_pRequest) {
        return m_pRequest;
    }
    m_pRequest = new CCHttpRequest();
    if (!m_pRequest) {
        return NULL;
    }
    
    //设置回调
    m_pRequest->setResponseCallback(this, callfuncND_selector(HttpSender::HttpCallBack));
    return m_pRequest;
}

void HttpSender::initRequest(const char *pUrl, CCHttpRequest::HttpRequestType type)
{
    if (!pUrl) {
        CCAssert(false, "Got an bad url !!");
        return;
    }
    
    if (!initRequest()) {
        //初始化失败
        CCLOG("Init HttpSender Error!!");
        return;
    }
    m_pRequest->setUrl(pUrl);
    m_pRequest->setRequestType(type);
}

void HttpSender::initRequest(const char *pUrl, CCHttpRequest::HttpRequestType type, const char *pData, int len)
{
    if (!pData || len<=0) {
        CCAssert(false, "Got an bad data");
        return;
    }
    this->initRequest(pUrl, type);
    m_pRequest->setRequestData(pData, len);
}

void HttpSender::HttpCallBack(CCNode *pRc, void *pData)
{
    if (!m_pAgent) {
        return;
    }
    m_pAgent->Callback(pRc, pData);
}

void HttpSender::send()
{
    CCHttpClient *pHttpClient = CCHttpClient::getInstance();
    pHttpClient->send(m_pRequest);
}

六,修改HelloWorldScene.h


对类ClassWorld添加继承类HttpCallbackTarget :

class HelloWorld : public cocos2d::CCLayer, public HttpCallbackTarget


添加函数定义:

void GetData(CCNode *pNode, void *pData);

void SendRequest(CCObject*, CCControlEvent);


添加成员变量:

HttpSender *m_pHttpSender;


七,在HelloWorldScene.cpp中添加测试代码


在init()函数中添加一个测试按钮“Send Requrest”:

CCControlButton* pButton = CCControlButton::create("Send request", "Thonburi", 34);
this->addChild(pButton, 1);
pButton->setPosition(ccp(size.width/2, 35));
pButton->addTargetWithActionForControlEvents(this, cccontrol_selector(HelloWorld::SendRequest), CCControlEventTouchDown);

实现发送函数:


void HelloWorld::SendRequest(CCObject* prc, CCControlEvent evt)
{
    if (!m_pHttpSender) {
        m_pHttpSender = new HttpSender(this);
    }
    m_pHttpSender->initRequest("http://127.0.0.1:8888", CCHttpRequest::kHttpGet);//连接我们自己的服务器
    m_pHttpSender->send();
    
    CCLOG("Send request !!!");
}

实现收到数据的回调函数:

void HelloWorld::GetData(CCNode *pNode, void *pData)
{
    if (!pData) {
        return;
    }
    
    CCHttpResponse *pResponse = (CCHttpResponse*)pData;
    if(pResponse->getResponseCode() != 200){
        //错误
        CCLOG("Error code is %d, and reason is %s ***", pResponse->getResponseCode(), pResponse->getErrorBuffer());
        return;
    }
    
    //数据
    std::vector<char>* pReceiveData = pResponse->getResponseData();
    std::stringstream oss;
    for (int i=0; i<pReceiveData->size(); ++i) {
        oss<<(*pReceiveData)[i];
    }
    
    std::string temp = oss.str();
    const char* buf = temp.c_str();
    CCLOG("Receive msg is = %s *** ", buf);
}

在此,我们只把我们收到的数据打印出来。


八,总结


这种对http服务进行了最简单的封装,没有设定超时的处理;每一个场景同时只能发送一个http请求。


源码:http://download.csdn.net/detail/thekingofc/7949617


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值