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