学习Cocos2d-x Lua:HTTP工具类封装

2015年03月24日 10:44 0 点赞 0 评论 更新于 2025-11-21 18:22

在这个系列中,我们将专注于学习Cocos2d-x Lua,总结Lua开发过程中涉及的知识点,以及如何在开发过程中使用Cocos Code IDE。本篇文章将详细讲解HTTP工具类的封装。

实现

该工具类对Cocos2d-x中的HttpClient进行了封装,从而可以在Lua中实现HTTP异步请求。

LuaHttpClient.h

#ifndef __LUAHTTPCLIENT_H__
#define __LUAHTTPCLIENT_H__

#include "cocos2d.h"
USING_NS_CC;

#include "cocos-ext.h"
USING_NS_CC_EXT;

// 参数封装类
class LuaParams {
public:
static LuaParams* create() {
LuaParams* params = new LuaParams(); // 参数在回调后释放
params->setTypeName("nil");
return params;
}

static LuaParams* create(const char* url, int func, const char* data, CCObject* obj, const char* typeName = "nil") {
LuaParams* params = new LuaParams();
params->setData(data);
params->setUrl(url);
params->setFunc(func);
params->setCCObjct(obj);
params->setTypeName(typeName);
return params;
}

void setFunc(int func_) {
func = func_;
}

int getFunc() {
return func;
}

void setCCObjct(CCObject* obj_) {
obj = obj_;
}

CCObject* getCCObjct() {
return obj;
}

void setTypeName(const char* typeName_) {
typeName = typeName_;
}

const char* getTypeName() {
return typeName;
}

void setUrl(const char* url_) {
url = url_;
}

const char* getUrl() {
return url;
}

void setData(const char* data_) {
data = data_;
}

const char* getData() {
return data;
}

private:
/** POST请求数据 **/
const char* data;
/** 请求地址 **/
const char* url;
/** Lua回调方法 **/
int func;
/** 用户数据 **/
CCObject* obj;
/** 用户数据类型名称 **/
const char* typeName;
};

// Lua异步http请求工具类
class LuaHttpClient : public CCObject {
public:
// 单例
static LuaHttpClient* getInstance();
// 异步Get请求
void asynGet(LuaParams* params);
// 异步Post请求
void asynPost(LuaParams* params);
// 回调函数
void callback(CCHttpClient* sender, CCHttpResponse* response);
};

#endif

LuaHttpClient.cpp

#include "LuaHttpClient.h"
#include "../cocos2dx_support/CCLuaEngine.h"

static LuaHttpClient* s_instance = NULL;

LuaHttpClient* LuaHttpClient::getInstance() {
if (s_instance == NULL) {
s_instance = new LuaHttpClient();
s_instance->autorelease();
}
return s_instance;
}

void LuaHttpClient::asynGet(LuaParams* params) {
CCHttpRequest* request = new CCHttpRequest();
request->setUrl(params->getUrl());
request->setRequestType(CCHttpRequest::kHttpGet);
request->setResponseCallback(this, httpresponse_selector(LuaHttpClient::callback));
request->setUserData((void*)params);
CCHttpClient::getInstance()->send(request);

if (params->getTypeName() != "nil") {
params->getCCObjct()->retain(); // 引用计数+1
}
}

void LuaHttpClient::asynPost(LuaParams* params) {
CCHttpRequest* request = new CCHttpRequest();
request->setUrl(params->getUrl());
request->setRequestType(CCHttpRequest::kHttpPost);
request->setResponseCallback(this, httpresponse_selector(LuaHttpClient::callback));
request->setUserData((void*)params);
// 写入POST数据
request->setRequestData(params->getData(), strlen(params->getData()));
CCHttpClient::getInstance()->send(request);
request->release();

if (params->getTypeName() != "nil") {
params->getCCObjct()->retain(); // 引用计数+1
}
}

void LuaHttpClient::callback(CCHttpClient* sender, CCHttpResponse* response) {
if (!response) {
return;
}

int statusCode = response->getResponseCode();
char statusString[64] = {};
sprintf(statusString, "HTTP Status Code: %d, tag = %s", statusCode, response->getHttpRequest()->getTag());
CCLog("response code: %d", statusCode);

// 回调Lua函数
LuaParams* params = (LuaParams*)response->getHttpRequest()->getUserData();

if (!response->isSucceed()) {
CCLog("response failed");
CCLog("error buffer: %s", response->getErrorBuffer());
// 释放内存
if (params->getTypeName() != "nil") {
params->getCCObjct()->release(); // 引用计数-1
}
delete params;
return;
}

// 转储数据
std::vector<char>* buffer = response->getResponseData();
std::string data(buffer->begin(), buffer->end());

CCLOG("request success");

CCLuaStack* pStack = CCLuaEngine::defaultEngine()->getLuaStack();
pStack->pushString(data.c_str()); // 把服务器回应的数据添加到函数参数1

if (params->getTypeName() != "nil") {
// 如果传递了CCObject,把它作为第二个参数
pStack->pushCCObject(params->getCCObjct(), params->getTypeName());
pStack->executeFunctionByHandler(params->getFunc(), 2);
pStack->clean();
params->getCCObjct()->release(); // 引用计数-1
} else {
// 第一个参数是函数的整数句柄,第二个参数是函数参数个数
pStack->executeFunctionByHandler(params->getFunc(), 1);
pStack->clean();
}
delete params;
}

绑定到Lua

工程下载

http://upyun.cocimg.com/cocos/Cocos2d-x_LuaHttpClient-master.zip

该工程使用Cocos2d-x-2.2.6和VS2012,将工程放到引擎projects目录下即可,具体步骤如下:

  1. 把“绑定自定义类到lua”目录下的ext文件夹放到cocos2d-x-2.2.6\scripting\lua目录下。
  2. 其它文件放到cocos2d-x-2.2.6\tools\tolua++目录下,点击build_ext.bat生成绑定文件。
  3. LuaExt.hLuaExt.cpp放到cocos2d-x-2.2.6\scripting\lua\cocos2dx_support下。
  4. 修改CCLuaStack.cpp,在init方法下调用tolua_Ext_open方法注册自定义C++类:
    #include "LuaExt.h" // 包含头文件
    m_state = lua_open();
    luaL_openlibs(m_state);
    tolua_Cocos2d_open(m_state);
    tolua_Ext_open(m_state);  // 注册自定义类
    toluafix_open(m_state);
    
  5. 在项目中引入文件。

点击查看:绑定C++自定义类到Lua

调用示例

在Lua中调用的示例代码如下:

-- 在主线程中创建一个CCLayer
local layer2 = CCLayerColor:create(ccc4(200,0,0,200))

-- 回调函数(参数1:服务返回的数据,参数2:用户数据(CCObject))
local callback = function(responseData, userdata)
cclog("lua response data : %s", responseData)
-- 替换场景
local scene = CCScene:create()
scene:addChild(userdata) -- 添加主线程中创建的CCLayer到场景
CCDirector:sharedDirector():replaceScene(scene)
end

-- 1. 异步http get请求并,传递一个CCObject
local params = LuaParams:create("http://www.baidu.com", callback, "", layer2, "CCLayer")
-- 2. 异步http get请求
-- local params = LuaParams:create()
-- params:setUrl("http://www.baidu.com")
-- params:setFunc(callback)
pClient:getInstance():asynGet(params) -- 发起请求

作者信息

boke

boke

共发布了 3994 篇文章