// 收到网络客户端的消息				  
int CGameModule::onClientMessage(const char* msgData, const unsigned int msgLen, const unsigned int msgId,
								 unsigned int serviceId, unsigned short moduleId, unsigned short protocolId, Connect* conn)
{
    if (protocolId >= MaxProtocolIDCount)
	{
		ReleaseErrorLog("receive net client msg error, protocolId = %d", protocolId);
		return InvalidParam;
	}

	ProtocolIdToHandler::const_iterator handlerIt = m_clientProtocolHanders->find(protocolId);
	if (handlerIt == m_clientProtocolHanders->end() || handlerIt->second.handler == NULL)
	{
		ReleaseErrorLog("not find the protocol handler for net client msg, protocolId = %d", protocolId);
		return NoFoundProtocolHandler;
	}
	
	// 填写消息上下文信息
	m_netClientContext.serviceId = serviceId;
	m_netClientContext.moduleId = moduleId;
	m_netClientContext.protocolId = protocolId;
	m_netClientContext.msgId = msgId;
	m_netClientContext.conn = conn;
	
	// 业务逻辑处理消息
	m_msgType = MessageType::NetClientMsg;
	(handlerIt->second.instance->*(handlerIt->second.handler))(msgData, msgLen, serviceId, moduleId, protocolId);

	m_netClientContext.protocolId = (unsigned short)-1;
	m_netClientContext.msgId = (unsigned int)-1;
	m_netClientContext.conn = NULL;
	
	return Success;
}
void CSrvMsgHandler::onLoad(const char* srvName, const unsigned int srvId, unsigned short moduleId)
{
	if (!GatewayProxyConfig::config::getConfigValue(CCfg::getValue("GatewayProxyService", "BusinessXmlConfigFile")).isSetConfigValueSuccess())
	{
		ReleaseErrorLog("set business xml config value error");
		stopService();
		return;
	}
	
    const DBConfig::config& dbCfg = DBConfig::config::getConfigValue(CCfg::getValue("GatewayProxyService", "DbConfigFile"));
	if (!dbCfg.isSetConfigValueSuccess())
	{
		ReleaseErrorLog("set db xml config value error");
		stopService();
		return;
	}

	if (!m_redisDbOpt.connectSvr(dbCfg.redis_db_cfg.center_db_ip.c_str(), dbCfg.redis_db_cfg.center_db_port,
	    dbCfg.redis_db_cfg.center_db_timeout * MillisecondUnit))
	{
		ReleaseErrorLog("gateway connect center redis service failed, ip = %s, port = %u, time out = %u",
		dbCfg.redis_db_cfg.center_db_ip.c_str(), dbCfg.redis_db_cfg.center_db_port, dbCfg.redis_db_cfg.center_db_timeout);
		
		stopService();
		return;
	}
	
	static const unsigned int gatewayProxySrvId = getSrvId();
	m_gatewayProxySrvData.ip = CSocket::toIPInt(CCfg::getValue("NetConnect", "NetIP"));  // 外网IP
	m_gatewayProxySrvData.port = atoi(CCfg::getValue("NetConnect", "Port"));
	m_gatewayProxySrvData.curTimeSecs = time(NULL);
	m_gatewayProxySrvData.currentPersons = 0;
	int rc = m_redisDbOpt.setHField(GatewayProxyListKey, GatewayProxyListKeyLen,
	                                (const char*)&gatewayProxySrvId, sizeof(gatewayProxySrvId), (const char*)&m_gatewayProxySrvData, sizeof(m_gatewayProxySrvData));
	if (rc != 0)
	{
		ReleaseErrorLog("set gateway proxy service data to redis center service failed, rc = %d", rc);
		stopService();
		return;
	}
	
	m_gameHallId = GatewayProxyConfig::config::getConfigValue().commonCfg.game_hall_id;
	
	// 定时保存数据到redis
	unsigned int millisecondUnit = 1000; // 秒转换为毫秒乘值
	unsigned int timerId = setTimer(millisecondUnit * atoi(CCfg::getValue("GatewayProxyService", "SaveDataToDBInterval")),
	                                (TimerHandler)&CSrvMsgHandler::saveDataToDb, 0, NULL, (unsigned int)-1);

    ReleaseInfoLog("gateway message handler load, service name = %s, id = %d, timer id = %u", srvName, srvId, timerId);
}
int CLogicHandler::sendMsgToProxy(const char* msgData, const unsigned int msgLen, unsigned short protocolId,
	                              ConnectProxy* conn, unsigned int serviceId, unsigned short moduleId, unsigned int msgId)
{
    int rc = m_service->sendMsgToProxy(msgData, msgLen, msgId, serviceId, moduleId, protocolId, conn);
	if (rc != Success) ReleaseErrorLog("send proxy message error3, msgLen = %u, serviceId = %d, moduleId = %d, protocolId = %d, rc = %d", msgLen, serviceId, moduleId, protocolId, rc);
	return rc;
}
int CGameModule::sendMsgToClient(const char* msgData, const unsigned int msgLen, unsigned short protocolId,
	                             Connect* conn, unsigned int serviceId, unsigned short moduleId, unsigned int msgId)
{
    int rc = m_service->sendMsgToClient(msgData, msgLen, msgId, serviceId, moduleId, protocolId, conn);
	if (rc != Success) ReleaseErrorLog("send client message error3, msgLen = %u, serviceId = %d, moduleId = %d, protocolId = %d, rc = %d", msgLen, serviceId, moduleId, protocolId, rc);
	return rc;
}
Example #5
0
// 向目标服务发送请求消息,默认自动发送上下文中存在的用户数据
// srcServiceProtocolId : 应答消息的处理协议ID,如果该消息存在应答的话
int CModule::sendMessage(const char* msgData, const unsigned int msgLen, unsigned short srcServiceType, unsigned int srcServiceId, unsigned short srcServiceProtocolId,
	                     unsigned int dstServiceId, unsigned short dstProtocolId, unsigned short dstModuleId, unsigned int msgId)
{
	int rc = m_service->sendMessage(srcServiceType, srcServiceId, msgData, msgLen, m_context.userData, m_context.userDataLen, m_context.srvAsyncDataFlag, m_context.srvAsyncDataFlagLen, dstServiceId, dstProtocolId, dstModuleId, 0, srcServiceProtocolId, m_context.userFlag, msgId);
	if (rc != Success) ReleaseErrorLog("send service message error4, msgLen = %u, dstServiceId = %d, dstProtocolId = %d, rc = %d", msgLen, dstServiceId, dstProtocolId, rc);
	return rc;
}
bool CDataHandler::readPkgHeader(Connect* curConn, unsigned int& dataSize)
{
	char netPkgHeader[netPkgHeaderLen] = {0};
	
	if (dataSize < netPkgHeaderLen) return false;
		
	if (readData(curConn, netPkgHeader, netPkgHeaderLen) != netPkgHeaderLen)
	{
		curConn->logicStatus = exception;  // 逻辑数据异常了
		ReleaseErrorLog("read net pkg header error, id = %lld, fd = %d, pkg header size = %d, data size = %d",
		curConn->id, curConn->fd, netPkgHeaderLen, dataSize);
		return false;
	}
	
	dataSize -= netPkgHeaderLen;  // 剩余数据量
	NetPkgHeader* pkgHeader = (NetPkgHeader*)netPkgHeader;
	if (pkgHeader->type == MSG)  // 用户数据包
	{
		pkgHeader->len = ntohl(pkgHeader->len);  // 注意长度需要转成主机字节序
		if (pkgHeader->len <= netPkgHeaderLen)
		{
			curConn->logicStatus = exception;  // 逻辑数据异常了
			ReleaseErrorLog("read user net pkg header error, id = %lld, fd = %d, pkg len = %d", curConn->id, curConn->fd, pkgHeader->len);
			return false;
		}

		curConn->needReadSize = pkgHeader->len - netPkgHeaderLen;  // 用户数据包长度
		return true;
	}
	else if (pkgHeader->type == CTL)  // 控制类型数据包
	{
		if (pkgHeader->cmd == HB_RP || pkgHeader->cmd == HB_RQ)  // 心跳应答消息,心跳请求包
		{
			curConn->heartBeatSecs = time(NULL);
			curConn->hbResult = 0;  // 连接正常
			
			static const NetPkgHeader hbReplyPkgHeader(htonl(netPkgHeaderLen), CTL, HB_RP);
			if (pkgHeader->cmd == HB_RQ) writeData(curConn, (const char*)&hbReplyPkgHeader, netPkgHeaderLen);  // 发送心跳应答消息包
			
			return (dataSize >= netPkgHeaderLen) ? readPkgHeader(curConn, dataSize) : false;  // 继续尝试读取数据包头部
		}
	}
	
	curConn->logicStatus = exception;  // 逻辑数据异常了
	ReleaseErrorLog("read net pkg header error, id = %lld, fd = %d, pkg len = %d, type = %d, cmd = %d", curConn->id, curConn->fd, pkgHeader->len, pkgHeader->type, pkgHeader->cmd);
	return false;
}
int CLogicHandler::sendMsgToProxy(const char* msgData, const unsigned int msgLen, unsigned short protocolId,
					              const char* userName, unsigned int serviceId, unsigned short moduleId, unsigned int msgId)
{
    int rc = (userName != NULL) ? m_service->sendMsgToProxy(msgData, msgLen, msgId, serviceId, moduleId, protocolId, getConnectProxy(userName)) : InvalidParam;
	if (rc != Success) ReleaseErrorLog("send proxy message error2, msgLen = %u, serviceId = %d, moduleId = %d, protocolId = %d, rc = %d, userName = %s",
	msgLen, serviceId, moduleId, protocolId, rc, (userName != NULL) ? userName : "");
	return rc;
}
bool CDataHandler::readPkgBody(Connect* curConn, unsigned int dataSize, unsigned int& pkgLen, char* pkgData)
{
	if (curConn->needReadSize > 0 && dataSize >= (unsigned int)curConn->needReadSize)
	{
		m_connMgr->setConnectNormal(curConn);  // 有数据则填写活跃时间点
		
		// 直接拷贝数据到缓冲区空间
		if (pkgData != NULL)
		{
			if ((unsigned int)curConn->needReadSize > pkgLen)
			{
				ReleaseErrorLog("read net pkg failed, need read size = %d, pkg buff size = %d", curConn->needReadSize, pkgLen);
				return false;
			}
			
			if (readData(curConn, pkgData, curConn->needReadSize) == (unsigned int)curConn->needReadSize)  // 从连接读出数据写入逻辑层buff
			{
				pkgLen = curConn->needReadSize;
				curConn->needReadSize = 0;  // 下一次读取数据包头部
				return true;
			}
			
			curConn->logicStatus = exception;  // 逻辑数据异常了
			ReleaseErrorLog("read net pkg data to buff error, id = %ld, fd = %d, need read size = %d, data size = %d",
			curConn->id, curConn->fd, curConn->needReadSize, dataSize);
			return false;
		}
				

		// 从逻辑层申请空间写数据
		BufferHeader* buffHeader = m_logicHandler->getBufferHeader();
		if (buffHeader != NULL)
		{
			if (readData(curConn, buffHeader->header, buffHeader->len) != buffHeader->len)  // 先读头部数据
			{
				curConn->logicStatus = exception;  // 逻辑数据异常了
				ReleaseErrorLog("read net pkg user header error, id = %ld, fd = %d, need read size = %d, data size = %d",
				curConn->id, curConn->fd, buffHeader->len, dataSize);
				return false;
			}
			curConn->needReadSize -= buffHeader->len;
		}
		
		void* logicCb = NULL;
		char* logicWriteBuff = m_logicHandler->getWriteBuffer(curConn->needReadSize, curConn->id, buffHeader, logicCb);
		if (curConn->needReadSize == 0) return true;  // 存在只有用户数据包头的情况
		
		if (logicWriteBuff != NULL)
		{
			bool isRead = (logicWriteBuff != (char*)-1);  // 是否直接丢弃数据,false则丢弃数据
			if (readData(curConn, logicWriteBuff, curConn->needReadSize, isRead) == (unsigned int)curConn->needReadSize)  // 从连接读出数据写入逻辑层buff
			{
				if (isRead) m_logicHandler->submitWriteBuffer(logicWriteBuff, curConn->needReadSize, curConn->id, logicCb);  // 提交数据到逻辑层
				curConn->needReadSize = 0;  // 下一次读取数据包头部
				return true;
			}
			
			curConn->logicStatus = exception;  // 逻辑数据异常了
			ReleaseErrorLog("read net pkg body error, id = %ld, fd = %d, need read size = %d, data size = %d",
			curConn->id, curConn->fd, curConn->needReadSize, dataSize);
		}
	}
	
	return false;
}
// 把data数据写入网络连接
bool CDataHandler::write(CConnectManager* connMgr, Connect* conn, const char* data, int len)
{
	int wtLen = 0;
	if (getCanWriteDataSize(conn) == 0)
	{
		// 先直接写到socket缓冲区
		if (!writeToSkt(connMgr, conn, data, len, wtLen)) return false;
		if (len == wtLen) return true;
		
		// 剩余未写完的数据写往临时缓冲区
		data += wtLen;
		len -= wtLen;
	}
	
	CSingleW_SingleR_Buffer* writeBuff = conn->writeBuff;
	if (writeBuff == NULL)
	{
	    // 第一次创建新内存块并挂接到链表上
		writeBuff = connMgr->getWriteBuffer();
		if (writeBuff == NULL)
		{
			ReleaseErrorLog("first time get no memory for write logic data to connect, id = %lld, fd = %d", conn->id, conn->fd);
			return false;  // 好吧,内存没了这种不可思议的事情居然出现了,估计哪里有内存泄露了,太疯狂了。。。
		}
		
		writeBuff->next = writeBuff;    // 整成环型链表读写循环
		conn->writeBuff = writeBuff;
		conn->curWriteIdx = writeBuff;
	}
		
	wtLen = writeBuff->write(data, len);
	if (wtLen < len)
	{
		// 下一块buff必须为空才能往里写数据,否则会导致读线程读的数据不连续而出现错误
		CSingleW_SingleR_Buffer* next = writeBuff->next;
		if (next != writeBuff && next->isEmpty())
		{
			char* readFlag = (char*)next;			
			if (*(--readFlag) == 0)  // 非当前正在读的buff才能执行写操作
			{
                conn->writeBuff = next;  // 条件满足则切换到下一块内存
			    return write(connMgr, conn, data + wtLen, len - wtLen);    
			}
		}

		// 创建新内存块并挂接到链表上
		CSingleW_SingleR_Buffer* newBuff = connMgr->getWriteBuffer();
		if (newBuff == NULL)
		{
			ReleaseErrorLog("no memory for write logic new data to connect, id = %lld, fd = %d", conn->id, conn->fd);
			return false;  // 好吧,内存没了这种不可思议的事情居然出现了,估计哪里有内存泄露了,太疯狂了。。。
		}
			
		newBuff->next = next;
		writeBuff->next = newBuff;
		conn->writeBuff = newBuff;  // 切换到下一块内存
		return write(connMgr, conn, data + wtLen, len - wtLen);
	}
	
	return true;
}
Example #10
0
// 服务模块收到消息				
int CModule::onServiceMessage(const char* msgData, const unsigned int msgLen, const char* userData, const unsigned int userDataLen,
							  unsigned short dstProtocolId, unsigned int srcSrvId, unsigned short srcSrvType,
							  unsigned short srcModuleId, unsigned short srcProtocolId, int userFlag, unsigned int msgId, const char* srvAsyncDataFlag, unsigned int srvAsyncDataFlagLen)
{
	// if (dstProtocolId >= MaxProtocolIDCount || srcSrvType >= MaxServiceType || userDataLen > MaxUserDataLen || srcProtocolId >= MaxProtocolIDCount)
	if (srcSrvType >= MaxServiceType || userDataLen > MaxUserDataLen)
	{
		ReleaseErrorLog("receive msg error, srcServiceId = %d, srcServiceType = %d, dstProtocolId = %d, userDataLen = %d, srcProtocolId = %d",
		                srcSrvId, srcSrvType, dstProtocolId, userDataLen, srcProtocolId);
		return InvalidParam;
	}
	
	CHandler* instance = NULL;
	ProtocolHandler handler = NULL;
	if (dstProtocolId < MaxProtocolIDCount)
	{
		MsgHandler& msgHandler = m_protocolHanders[srcSrvType][dstProtocolId];
		if (msgHandler.handler == NULL) msgHandler = m_protocolHanders[CommonSrv][dstProtocolId];  // 默认取公共协议
		if (msgHandler.handler != NULL)
		{
			instance = msgHandler.instance;
			handler = msgHandler.handler;
		}
	}
	else
	{
		ProtocolIdToHandler::const_iterator handlerIt = m_serviceProtocolHandler.find(dstProtocolId);
		if (handlerIt != m_serviceProtocolHandler.end() && handlerIt->second.handler != NULL)
		{
			instance = handlerIt->second.instance;
			handler = handlerIt->second.handler;
		}
	}
	
	if (instance == NULL)
	{
		ReleaseErrorLog("can not find the protocol handler, srcServiceId = %d, srcServiceType = %d, dstProtocolId = %d", srcSrvId, srcSrvType, dstProtocolId);
		return NoFoundProtocolHandler;
	}
	
	// 填写消息上下文信息
	m_context.srcSrvId = srcSrvId;
	m_context.srcSrvType = srcSrvType;
	m_context.srcModuleId = srcModuleId;
	m_context.srcProtocolId = srcProtocolId;
	m_context.dstProtocolId = dstProtocolId;
	
	if (userDataLen > 0) memcpy(m_context.userData, userData, userDataLen);
	m_context.userData[userDataLen] = '\0';
	m_context.userDataLen = userDataLen;
	m_context.userFlag = userFlag;
	
	// 异步数据标识
	if (srvAsyncDataFlagLen > 0) memcpy(m_context.srvAsyncDataFlag, srvAsyncDataFlag, srvAsyncDataFlagLen);
	m_context.srvAsyncDataFlag[srvAsyncDataFlagLen] = '\0';
	m_context.srvAsyncDataFlagLen = srvAsyncDataFlagLen;
	
	// 业务逻辑处理消息
	m_msgType = MessageType::InnerServiceMsg;
	(instance->*handler)(msgData, msgLen, srcSrvId, srcModuleId, srcProtocolId);
	
	m_context.dstProtocolId = (unsigned short)-1;
	m_context.userData[0] = '\0';
	m_context.userDataLen = 0;
	m_context.userFlag = 0;

	m_context.srvAsyncDataFlag[0] = '\0';
	m_context.srvAsyncDataFlagLen = 0;
	
	return Success;
}