首页 > 代码库 > Cocos2d-x3.1 HttpClient封装与使用

Cocos2d-x3.1 HttpClient封装与使用

1、首先给出封装后的工具类:HttpManager

#include "cocos2d.h"
#include "../cocos2d/extensions/cocos-ext.h"
#include "network/HttpClient.h"
USING_NS_CC;
USING_NS_CC_EXT;
using namespace network;
class  HTTPManagerDelegate
{
public:
   virtual void onHttpManagerRequestCompleted(cocos2d::network::HttpClient *sender, cocos2d::network::HttpResponse *response) = 0;
};

class HTTPManager:public Ref
{
public:
    HTTPManager();
    ~HTTPManager();
    CC_SYNTHESIZE(HTTPManagerDelegate*, _httpManagerDelegate, HttpDelegate);
    //Http Response Callback
    void onHttpRequestCompleted(cocos2d::network::HttpClient *sender, cocos2d::network::HttpResponse *response);
    void getFormData(std::string parameter);
    void sendGetRequest(std::string url,std::string requestTag);
    void writeFileFromRequest(cocos2d::network::HttpResponse *response,std::string filename);
    typedef std::function<void(cocos2d::network::HttpClient *sender, cocos2d::network::HttpResponse *response)> ccHttpManagerCallback;
    void addHttpListener(ccHttpManagerCallback& callback);

private:
    ccHttpManagerCallback _eventCallback;
};

#include "HTTPManager.h"
#include <iostream>


//#include "../UnZip/DJZipArchive.h"
#define HTTPHeader "http://www.epicc.com.cn/QrDmzBastionNB/BastionServlet"

HTTPManager::HTTPManager()
{
}
HTTPManager::~HTTPManager()
{
}
void HTTPManager::sendGetRequest(std::string url,std::string requestTag)
{
    HttpRequest* request = new HttpRequest();//使用HttpRequest无参的构造函数,提供了一个很好的默认设置
    request->setRequestType(cocos2d::network::HttpRequest::Type::GET);//设置连接方式,常用GET和POST
    request->setUrl(url.c_str());//设置连接地址
    //设置回调,在onHttpRequestCompleted中读取数据
    request->setResponseCallback(CC_CALLBACK_2(HTTPManager::onHttpRequestCompleted, this));
    request->setTag(requestTag.c_str());//设置Tag
    network::HttpClient::getInstance()->send(request);//添加到HttpClient任务队列
    request->release();//释放连接
}

void HTTPManager::getFormData(std::string parameter)
{
    HttpRequest* request = new HttpRequest();
    request->setUrl(HTTPHeader);
    request->setRequestType(HttpRequest::Type::POST);
    
    request->setResponseCallback(CC_CALLBACK_2(HTTPManager::onHttpRequestCompleted, this));
    
    
    //write the post data
    const char* postData = StringUtils::format("parameter=%s",parameter.c_str()).c_str();
    log("postData = %s",postData);
    request->setRequestData(postData, strlen(postData));
    request->setTag("getFormData");
    log("url = %s",request->getUrl());
    
    HttpClient::getInstance()->send(request);
    request->release();
}

void HTTPManager::onHttpRequestCompleted(cocos2d::network::HttpClient *sender, cocos2d::network::HttpResponse *response)
{
    if (!response) {
        return;
    }
    
    
    if (0 != strlen(response->getHttpRequest()->getTag())) {
        log("%s compeled",response->getHttpRequest()->getTag());
    }
    
    long statusCode = response->getResponseCode();
    
    char statusString[64] = {};
    
    sprintf(statusString, "HTTP Status Code:%ld , tag = %s",statusCode,response->getHttpRequest()->getTag());
    log("response code:%s",statusString);
    
    
    if (!response->isSucceed()) {
        log("response failed");
        log("error buffer:%s",response->getErrorBuffer());
        return;
    }

    
    if (_httpManagerDelegate) {
        _httpManagerDelegate->onHttpManagerRequestCompleted(sender, response);
    }
    
       
    
    const char* resTag = response->getHttpRequest()->getTag();
}

void HTTPManager::writeFileFromRequest(cocos2d::network::HttpResponse *response,std::string filename)
{
    
    std::vector<char>* buffer = response->getResponseData();
    printf("Http Test,dump data:");
    std::string path= FileUtils::getInstance()->getWritablePath();
    std::string fullPath =  path + filename;
    FILE* fp = fopen(fullPath.c_str(), "wb");
    

    log("将文件写入本地 %s",fullPath.c_str());
    
    
    
    unsigned char bf;
    for (unsigned int i  = 0; i < buffer->size(); i++) {
        
        bf = buffer->at(i);
        fwrite(&bf, 1, 1, fp);
        
    }
    fclose(fp);
    
}

void HTTPManager::addHttpListener(ccHttpManagerCallback &callback)
{
    _eventCallback = callback;
    
}

        为提高代码可用性,此处一些方法接口并没用到,但是以防以后用到,还是贴了出来,下面看看使用实例。

2、使用实例

        使用类需继承HttpManagerDelegate,用来委托事件。

#include "cocos2d.h"
#include "HTTPManager.h"
USING_NS_CC;

class HelloWorld : public cocos2d::Layer,public HTTPManagerDelegate
{
public:
    // there's no 'id' in cpp, so we recommend returning the class instance pointer
    static cocos2d::Scene* createScene();

    // Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone
    virtual bool init();  
    
    // a selector callback
    void menuCloseCallback(cocos2d::Ref* pSender);
    
    virtual void onHttpManagerRequestCompleted(cocos2d::network::HttpClient *sender, cocos2d::network::HttpResponse *response) ;
    
    void writeFileFromRequest(cocos2d::network::HttpResponse *response,std::string filename);

    
    // implement the "static create()" method manually
    CREATE_FUNC(HelloWorld);
};

#include "HelloWorldScene.h"
#include "HTTPManager.h"
USING_NS_CC;

Scene* HelloWorld::createScene()
{
    // 'scene' is an autorelease object
    auto scene = Scene::create();
    
    // 'layer' is an autorelease object
    auto layer = HelloWorld::create();

    // add layer as a child to scene
    scene->addChild(layer);

    // return the scene
    return scene;
}

// on "init" you need to initialize your instance
bool HelloWorld::init()
{
    //////////////////////////////
    // 1. super init first
    if ( !Layer::init() )
    {
        return false;
    }
    
    Size visibleSize = Director::getInstance()->getVisibleSize();
    Vec2 origin = Director::getInstance()->getVisibleOrigin();

    /////////////////////////////
    // 2. add a menu item with "X" image, which is clicked to quit the program
    //    you may modify it.

    // add a "close" icon to exit the progress. it's an autorelease object
    auto closeItem = MenuItemImage::create(
                                           "CloseNormal.png",
                                           "CloseSelected.png",
                                           CC_CALLBACK_1(HelloWorld::menuCloseCallback, this));
    
	closeItem->setPosition(Vec2(origin.x + visibleSize.width - closeItem->getContentSize().width/2 ,
                                origin.y + closeItem->getContentSize().height/2));

    // create menu, it's an autorelease object
    auto menu = Menu::create(closeItem, NULL);
    menu->setPosition(Vec2::ZERO);
    this->addChild(menu, 1);

    auto httpManager = new HTTPManager();
    httpManager->retain();
    httpManager->setHttpDelegate(this);
    httpManager->sendGetRequest("localhost:8080/qwe.json", "update_time");
    return true;
}

void HelloWorld::onHttpManagerRequestCompleted(cocos2d::network::HttpClient *sender, cocos2d::network::HttpResponse *response)
{
        if (strcmp(response->getHttpRequest()->getTag(), "update_time") == 0)
        {
            writeFileFromRequest(response,"qwe.json");
            log("下载更新包");
            std::string version = "version";
            std::string table = "version";
            if (!(strcmp(version.c_str(), table.c_str()) == 0))
            {
                log("下载更新包");
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
                
#endif
            }
            
            
        }
        
        
        if (strcmp(response->getHttpRequest()->getTag(), "update_mobile") == 0)
        {
            
            log("update_mobile");
        }
        
}

void HelloWorld::writeFileFromRequest(cocos2d::network::HttpResponse *response,std::string filename)
{
    std::vector<char>* buffer = response->getResponseData();
    printf("Http Test,dump data:");
    std::string path= FileUtils::getInstance()->getWritablePath();
    std::string fullPath =  path + filename;
    FILE* fp = fopen(fullPath.c_str(), "wb");
    
    
    log("将文件写入本地 %s",fullPath.c_str());
//    auto size = buffer->size();
//    unsigned char bf[size];
//    fwrite(bf, size, 1, fp);
    
    unsigned char bf;
    for (unsigned int i  = 0; i < buffer->size(); i++) {
        
        bf = buffer->at(i);
        fwrite(&bf, 1, 1, fp);
        
    }
    fclose(fp);

}

void HelloWorld::menuCloseCallback(Ref* pSender)
{
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) || (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
	MessageBox("You pressed the close button. Windows Store Apps do not implement a close button.","Alert");
    return;
#endif

    Director::getInstance()->end();

#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
    exit(0);
#endif
}

3、使用类

        只要继承HttpManagerDelegate委托,即可实现函数的回调。其次,需要搭建服务器。关于函数的委托回调,前面有研究。

        (1)设置两个参数setHttpManagerDelegate(this),方便回调该HelloWorld类的onHttpManagerRequestCompleted函数

        (2)设置setGetRequest();第一个参数是URL,第二个是Tag。

4、流程

Eclipse ADT 导入HttpServer工程,运行,就可运行服务器。
关闭网络链接。
运行cocos2d-x工程
在网页地址栏输入:localhost:8080/文件名
注意:保存文件的后台路径需要自己修改

源码链接:http://download.csdn.net/user/yuxikuo_1/uploads

Cocos2d-x3.1 HttpClient封装与使用