1.为了让麻将同时支持TCP长连模式 ,和http短连模式,需要开启新的线程来支持
而cocos2dx本身对多线程支持并不是很好,所以需要用到,
#include "pthread.h"
并且需要引入pthreadVSE2.lib静态链接库
来维持多线程,监听网络消息数据
CLobbyCommon.h
网络状态定义:
typedef enum
{
_LOBBY_NET_NULL_ = 0,//无连接
_LOBBY_NET_ING_, //连接中
_LOBBY_NET_SUCCESS_, //连接成功
_LOBBY_NET_FAILED_, //链接失败
_LOBBY_NET_ERROR_ //连接错误
}LOBBY_NET_STATUS;
class CLobbyCommon
{
public:
CLobbyCommon();
~CLobbyCommon();
public:
static CLobbyCommon* getInstance(void);
static void DeleteInstance(void);
CMyNetWork* GetNetHandle(void);
pthread_t m_theradID;//线程ID
int StartDownLoading( char* path, int type, char* postBuf, int len, int bIsHT = 0);
int StopDownLoading(int handle);
static void LobbyNetCallBack( int event, int index, void* buf, int len );
private:
static CLobbyCommon* instance;
class CGarbo // 它的唯一工作就是在析构函数中删除CSingleton的实例
{
public:
~CGarbo()
{
if (CLobbyCommon::instance)
delete CLobbyCommon::instance;
}
};
static CGarbo Garbo; // 声明一个静态成员,在程序结束时,系统会调用它的析构函数,注意这里仅仅是声明,还需要在相应的cpp文件中对静态成员进行定义哦。
//(疑问:静态成员变量是何时被销毁的,是该单例类的对象调用析构函数的时候被销毁的吗,还是直到系统结束后才被销毁)
public:
CMyNetWork m_lobby_net;//http 网络模块
int m_netHandle[3];//同时支持多个http连接,比如计费数据和其他网络请求
char m_netBuf[1024]; //数据
int m_netBufLen; //数据下发的长度
int m_netStatus; //网络状态
int m_nethandle; //单次连接网络句柄
};
在麻将公共模块单例类的构造函数中开启新线程
CLobbyCommon::CLobbyCommon()
{
pthread_create( &m_theradID, NULL, Run, NULL ); //创建线程
}
析构函数中阻塞当前线程直到他的主线程结束而销毁
CLobbyCommon::~CLobbyCommon()
{
m_exit = 1;
pthread_join( m_theradID, NULL ); //阻塞当前的线程,直到另外一个线程运行结束
}
线程的执行函数循环执行网络模块run方法
void* CLobbyCommon::Run(void* argv)
{
while( 1 )
{
CLobbyCommon::getInstance()->m_lobby_net.run();//运行网络模块run监听网络数据
#ifdef _WIN32
sleep( 1000 );//1秒1次
#else
sleep( 1 );
#endif
}
return NULL;
}
发送和下载数据
void CLobbyCommon::LobbyNetCallBack( int event, int index, void* buf, int len )
{
if ( event == NET_CON_SUCCESS )
{
if( index == instance->m_netHandle[0] ) //??
{
instance->m_netBufLen = 0;
memset( instance->m_netBuf, 0, _NET_BUF_LEN_ );
}
else if( index == instance->m_netHandle[1] )
{
instance->m_billnetBufLen = 0;
memset( instance->m_billnetBuf, 0, _NET_BUF_LEN_ );
}
}
else if ( event == NET_READ )
{
if( index == instance->m_netHandle[0] )
{
memcpy( instance->m_netBuf, buf, len ); //得到下载数据
instance->m_netBufLen += len;
}
else if( index == instance->m_netHandle[1] )
{
memcpy( instance->m_billnetBuf, buf, len );
instance->m_billnetBufLen += len;
}
}
else if( event == NET_FINISH )
{
int status = instance->m_lobby_net.isSuccess(index);
int netstatus = (status == 1) ? _LOBBY_NET_SUCCESS_ : _LOBBY_NET_FAILED_;
if( index == instance->m_netHandle[0] )
{
instance->m_netStatus = netstatus;
}
else if( index == instance->m_netHandle[1] )
{
instance->m_billnetStatus = netstatus;//计费网络
}
instance->StopDownLoading(index);
}
else if( event <= NET_ERROR )
{
if( index == instance->m_netHandle[0] )
{
instance->m_netStatus = _LOBBY_NET_ERROR_;
}
else if( index == instance->m_netHandle[1] )
{
instance->m_billnetStatus = _LOBBY_NET_ERROR_;//计费网络?
}
instance->StopDownLoading(index);
}
}
//下载数据 //发送数据 数据长度
int CLobbyCommon::StartDownLoading( char* path, int type, char* postBuf, int len, int bIsHT )
{
char strURL[256] = {0};
long ip =MJCommon::getInstance()->WebServiceInfo.dwIp;
if( (path == NULL) || (strlen(path) == 0) )
{
return -1;
}
sprintf( strURL, "http://%s:%d/%s&qudao=%d&ver=%d", inet_ntoa( *(in_addr*)&ip ), MJCommon::getInstance()->WebServiceInfo.dwPort, path, _USER_QUDAO_,VERSION_CODE );
int handle = m_lobby_net.CreateNet( strURL, MJCommon::getInstance()->WebServiceInfo.dwPort, type, CLobbyCommon::getInstance()->LobbyNetCallBack, postBuf, len ); //这里下载数据
if( handle >= 0 )
{
if ( bIsHT == 0 )
{
m_netStatus = _LOBBY_NET_ING_;
m_netHandle[0] = handle;
}
else //下载计费数据
{
m_billnetStatus = _LOBBY_NET_ING_;
m_netHandle[1] = handle;
}
}
return handle;
}
int CLobbyCommon::StopDownLoading( int handle )
{
for ( int i = 0; i < MAX_NET; i++ )
{
if( m_netHandle[i] == handle )
{
m_lobby_net.DeleteNet( handle );
m_netHandle[i] = -1;
}
}
return 0;
}