#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; }
使用类需继承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 }
只要继承HttpManagerDelegate委托,即可实现函数的回调。其次,需要搭建服务器。关于函数的委托回调,前面有研究。
(1)设置两个参数setHttpManagerDelegate(this),方便回调该HelloWorld类的onHttpManagerRequestCompleted函数
(2)设置setGetRequest();第一个参数是URL,第二个是Tag。
Eclipse ADT 导入HttpServer工程,运行,就可运行服务器。
关闭网络链接。
运行cocos2d-x工程
在网页地址栏输入:localhost:8080/文件名
注意:保存文件的后台路径需要自己修改
源码链接:http://download.csdn.net/user/yuxikuo_1/uploads
原文地址:http://blog.csdn.net/yuxikuo_1/article/details/39255967