Exemple #1
0
void Worker::closeClient(Connection *client)
{
	ClientData *pData = (ClientData*)client->getData();
	std::string sid = pData->session.getId();
	LOG("close client, fd=%d, sid=%s", client->getSocket().getFd(), sid.c_str());
	
	//router通知
	sendToRouter(ROUTER_MSG_CLOSE, SID_LENGTH, pData->session.getId(), 0, NULL);
	
	//后端通知
	Config *pConfig = Config::getInstance();
	if(pConfig->bEventClose){
		Backend *backend = new Backend(pEventLoop, NULL, NULL);
		backend->copyParam(pData->params);
		backend->addParam("EVENT", sizeof("EVENT") - 1, "2", 1);
		backend->setCloseHandler(EV_CB(this, Worker::onBackendClose));
		backend->setResponseHandler(EV_CB(this, Worker::onBackendResponse));
		if(!backend->run()){
			delete backend;
		}
	}
	
	//释放后端请求
	for(BackendList::const_iterator it = pData->backends.begin(); it != pData->backends.end(); ++it){
		Backend *backend = it->first;
		backend->setClient(NULL);
		backend->shutdown();
	}
	
	//取消频道订阅
	for(ChannelSet::const_iterator it2 = pData->channels.begin(); it2 != pData->channels.end(); ++it2){
		const std::string &chname = it2->first;
		
		ChannelList::iterator cit = arrChannels.find(chname);
		if(cit != arrChannels.end()){
			cit->second.erase(client);
			if(cit->second.empty()){
				sendToRouter(ROUTER_MSG_CH_UNSUB, chname.size(), chname.c_str(), 0, NULL);
				arrChannels.erase(cit);
			}
		}
	}
	
	//计数更新
	pMaster->delClient(nId);
	
	//客户端列表更新
	arrClients.erase(sid);
	
	//lua更新
	if(pMaster->pScript && pMaster->pScript->hasCloseProc()){
		pMaster->pScript->procClose(client);
	}
	
	delete pData;
	delete client;
}
Exemple #2
0
void GamePool::initialize(EventLoop* loop)
{
	pLoop = loop;
	for (int i = 0; i < 1;i++)
	{
		GameConnection* gConn = new GameConnection(pLoop);
		gConn->setConnectHandler(EV_CB(this,GamePool::onConnected));
		gConn->setCloseHandler(EV_CB(this, GamePool::onClose));
	}
}
Exemple #3
0
void Worker::createClient(int fd, const char *host, int port)
{
	//创建session对像
	Session sess(nPid, fd);
	LOG("new client, fd=%d, host=%s, port=%d, sid=%s", fd, host, port, sess.getId());
	
	//环镜变量
	ClientData *pData = new ClientData();
	char szPort[8];
	int nPort = sprintf(szPort, "%d", port);
	pData->session = sess;
	pData->nrequest = 0;
	Backend::makeParam(pData->params, "REMOTE_ADDR", sizeof("REMOTE_ADDR") - 1, host, strlen(host));
	Backend::makeParam(pData->params, "REMOTE_PORT", sizeof("REMOTE_PORT") - 1, szPort, nPort);
	Backend::makeParam(pData->params, "SESSIONID", sizeof("SESSIONID") - 1, sess.getId(), SID_LENGTH);
	
	//创建连接对像
	Connection *client = new Connection(pEventLoop, fd);
	client->setHostAndPort(host, port);
	client->setData(pData);
	client->setMessageHandler(EV_CB(this, Worker::onMessage));
	client->setCloseHandler(EV_CB(this, Worker::onClose));
	//client->setWriteCompleteHandler(EL_CB(this, Worker::onWriteComplete));
	
	arrClients[sess.getId()] = client;
	
	//计数更新
	pMaster->addClient(nId);
	
	//Router通知
	sendToRouter(ROUTER_MSG_CONN, SID_LENGTH, sess.getId(), 0, NULL);
	
	//backend通知
	Config *pConfig = Config::getInstance();
	if(pConfig->bEventConnect){
		Backend *backend = new Backend(pEventLoop, client, NULL);
		backend->copyParam(pData->params);
		backend->addParam("EVENT", sizeof("EVENT") - 1, "1", 1);
		backend->setCloseHandler(EV_CB(this, Worker::onBackendClose));
		backend->setResponseHandler(EV_CB(this, Worker::onBackendResponse));
		if(backend->run()){
			pData->backends[backend] = 1;
		}else{
			delete backend;
		}
	}
	
	//lua通知
	if(pMaster->pScript && pMaster->pScript->hasConnectProc()){
		pMaster->pScript->procConnect(client);
	}
}
Exemple #4
0
void Worker::initRouter()
{
	//connect router
	Config *pConfig = Config::getInstance();
	pRouter = new Connection(pEventLoop);
	pRouter->setTimeout(3000);
	pRouter->setConnectHandler(EV_CB(this, Worker::onRouterConnect));
	pRouter->setMessageHandler(EV_CB(this, Worker::onRouterMessage));
	pRouter->setCloseHandler(EV_CB(this, Worker::onRouterClose));
	pRouter->connectTcp(pConfig->sRouterHost.c_str(), pConfig->nRouterPort);
	LOG_INFO("connect router server %s:%d", 
		pConfig->sRouterHost.c_str(), 
		pConfig->nRouterPort);
}
Exemple #5
0
void Router::onConnection(int fd, int ev, void *data)
{
	LOG("new client");
	Connection *conn = new Connection(pEventLoop, fd);
	conn->setMessageHandler(EV_CB(this, Router::onMessage));
	conn->setCloseHandler(EV_CB(this, Router::onClose));
	
	//info
	GatewayInfo *pInfo = new GatewayInfo();
	pInfo->isauth = false;
	pInfo->serverid = 0;
	conn->setData(pInfo);
	
	allGateways[conn] = 1;
}
Exemple #6
0
void Worker::proc()
{
	//还原信号默认处理方式
	signal(SIGTERM, NULL);
	signal(SIGUSR1, NULL);

	//set process title
	Config *cfg = Config::getInstance();
	char title[256];
	snprintf(title, 256, "fooking gateway worker, %s", cfg->sFile.c_str());
	utils::setProcTitle(title);
	
	//create loop
	pEventLoop = new EventLoop();
	pEventLoop->setMaxWaitTime(500);
	pEventLoop->addEventListener(nPipefd, EV_IO_READ, EV_IO_CB(this, Worker::onChannel), NULL);
	pEventLoop->setLoopBefore(EV_CB(this, Worker::loopBefore), NULL);
	
	//listen server
	pServer = new Server(pEventLoop, pMaster->pServer->getSocket().getFd());
	pServer->setConnectionHandler(EV_IO_CB(this, Worker::onConnection));
	if(!pMaster->bUseAcceptMutex){
		pServer->start();
	}
	
	//init router
	initRouter();
	
	//backend env
	char root[256];
	char name[256];
	int rootlen = sprintf(root, "%s/%s", cfg->sFastcgiRoot.c_str(), cfg->sFastcgiFile.c_str());
	int namelen = sprintf(name, "/%s", cfg->sFastcgiFile.c_str()); 
	Backend::addSharedParam("REQUEST_METHOD", strlen("REQUEST_METHOD"), "POST", strlen("POST"));
	Backend::addSharedParam("SCRIPT_FILENAME", strlen("SCRIPT_FILENAME"), root, rootlen);
	Backend::addSharedParam("SCRIPT_NAME", strlen("SCRIPT_NAME"), name, namelen);
	Backend::addSharedParam("DOCUMENT_ROOT", strlen("DOCUMENT_ROOT"), cfg->sFastcgiRoot.c_str(), cfg->sFastcgiRoot.size());
	
	//backend env from config.lua
	FastcgiParams::const_iterator it;
	for(it = cfg->arFastcgiParams.begin(); it != cfg->arFastcgiParams.end(); ++it){
		std::string k = it->first;
		std::string v = it->second;
		Backend::addSharedParam(k.c_str(), k.size(), v.c_str(), v.size());
	}
	
	LOG("worker started, pipefd=%d", nPipefd);
	pEventLoop->run();
}
Exemple #7
0
void Router::setMaster(ServiceConnection* service)
{
	pMaster = service;
	pMaster->setMessageHandler(EV_CB(this, Router::onMasterMessage));
}
Exemple #8
0
void Router::addClientForRoute(Client* client)
{
	addClient(client);
	client->connection->setMessageHandler(EV_CB(this, Router::doClientRoute));
}
Exemple #9
0
void Worker::onMessage(Connection *client)
{
	Buffer *pBuffer = client->getBuffer();
	ClientData *pData = (ClientData*)client->getData();
	
	LOG("client message, fd=%d, len=%d", client->getSocket().getFd(), pBuffer->size());
	
	while(pBuffer->size())
	{
		bool proc = false;
		Buffer *msg = new Buffer();
		
		//自定义协议处理
		if(pMaster->pScript && pMaster->pScript->hasInputProc()){
			int ret = pMaster->pScript->procInput(client, pData->nrequest, pBuffer, msg);
			if(ret < 0){
				delete msg;
				return ;
			}else if(ret > 0){
				proc = true;
			}
		}
		
		//原生协议处理
		if(!proc){
			//check head
			size_t hdrSize = 4;
			if(pBuffer->size() < hdrSize){
				LOG("message head not enough");
				delete msg;
				return ;
			}
			
			//check body
			size_t msgSize = net::readNetInt32(pBuffer->data());
			if(pBuffer->size() < hdrSize + msgSize){
				LOG("message body size not enough, msgSize=%d, buffSize=%d", msgSize, pBuffer->size());
				delete msg;
				return ;
			}
			
			msg->append(pBuffer->data() + hdrSize, msgSize);
			
			pBuffer->seek(hdrSize + msgSize);
		}
	
		pData->nrequest++;
		LOG("process message, fd=%d, reqid=%d, proc=%d, buffer size=%d, msg len=%d", 
			client->getSocket().getFd(), 
			pData->nrequest,
			proc, 
			pBuffer->size(),
			msg->size());
	
		//create request
		if(!msg->empty()){
			Backend *backend = new Backend(pEventLoop, client, msg);
			backend->copyParam(pData->params);
			backend->setCloseHandler(EV_CB(this, Worker::onBackendClose));
			backend->setResponseHandler(EV_CB(this, Worker::onBackendResponse));
			if(backend->run()){
				pData->backends[backend] = 1;
			}else{
				delete backend;
				LOG_ERR("not found backend server");
			}
		}
	}
}