示例#1
0
	SharedPointer<ConnInfo> BaseProxy::get_Conn(){
        SharedPointer<ConnInfo> conn;
        if (_use_existing_socket) {
            conn = ConnectionManager::get_instance()->get_connection(_name);
        } else {
            SharedPointer<BinaryProtocol> prot;
			bool ok=false;

			while(_protocols.get(prot, 10)==0&&!ok){ //deal CLOSE_WAIT connect 
				if(prot.is_valid()&&prot->getTransport().is_valid()){
					if((ok=SocketTool::is_ok(prot->getTransport()->id()))){
						conn=SharedPointer<ConnInfo>(new(std::nothrow)ConnInfo(prot));
						break;
					}
				}
			}

            if(!ok){
                conn=create_Conn();
            }
        }
        
        if (conn.is_valid() && conn->proto.is_valid() 
            && conn->proto->getTransport().is_valid()) { 
            int32_t tm = 0;
            if (get_property(PROXY_SEND_TIMEOUT, tm)) { 
                SocketTool::set_sndtimeout(conn->proto->getTransport()->id(), tm);
            }
            if (get_property(PROXY_RECV_TIMEOUT, tm)) {
                SocketTool::set_rcvtimeout(conn->proto->getTransport()->id(), tm);
            }
        }

        return conn;
    }
示例#2
0
    int32_t ServiceManager::add_service(SharedPointer<IProcessor> processor) {
        BGCC_TRACE("bgcc", "ServiceManager::add_service");
        std::string name;
        bool exist;
     
        if (processor.is_valid()) {
            name = processor->get_name();
        }
        else {
            BGCC_NOTICE("bgcc", "Failed to add service, because param is NULL");
            return -1;
        }

        Guard<Mutex> guard(&_mutex);
        if (!guard.is_locked()) {
            BGCC_WARN("bgcc", "Failed to lock mutex");
            return -1;
        }

        exist = _name2service.find(name) != _name2service.end();
        if (!exist) {
            std::pair<name2service_map::iterator, bool> v =
                _name2service.insert(std::make_pair(name, processor));

            if (false == v.second) {
                return -1;
            }
        }

        return 0;
    }
示例#3
0
/*
 * Class:     bgcc_Transaction
 * Method:    getCurrentTicketId
 * Signature: (Lbgcc/Protocol;ILjava/lang/String;)I
 */
JNIEXPORT jint JNICALL Java_bgcc_Transaction_getCurrentTicketId
  (JNIEnv *env, jobject transaction, jobject protocol, jint threadId, jstring fnName) {
      BGCC_TRACE("bgcc", "Transaction::getCurrentTicketId begin");
      jclass transactionCls = env->GetObjectClass(transaction);
      jfieldID transactionAddressFid = env->GetFieldID(transactionCls, "transactionAddress", "J");

      jclass protocolCls = env->GetObjectClass(protocol);
      jfieldID protocolAddressFid = env->GetFieldID(protocolCls, "protocolAddress", "J");

      SharedPointer<IProtocol>* pProtocol =
          (SharedPointer<IProtocol>*)env->GetLongField(protocol, protocolAddressFid);
      if (!pProtocol || pProtocol->is_valid()) {
          BGCC_WARN("bgcc", "protocol is null");
          return 0;
      }

      const char* pFnName = env->GetStringUTFChars(fnName, NULL);
      if (pFnName == NULL) {
          BGCC_WARN("bgcc", "Allocate fnName failed");
          return 0;
      }

      Transaction* pTransaction = (Transaction*)env->GetLongField(transaction, transactionAddressFid);
      if (!pTransaction) {
          BGCC_WARN("bgcc", "transaction is null");
          return 0;
      }
      int32_t ticketId = pTransaction->getCurrentTicketId(*pProtocol, (int32_t)threadId, pFnName);
      env->ReleaseStringUTFChars(fnName, pFnName);

      BGCC_TRACE("bgcc", "Transaction::getCurrentTicketId end\n");
      return ticketId;
  }
示例#4
0
 int32_t ServiceManager::remove_service(SharedPointer<IProcessor> processor) {
     //NOTE: 本函数不用加锁
     std::string name;
     if (processor.is_valid()) {
         name = processor->get_name();
     }
     else {
         return -1;
     }
     return remove_service(name);
 }
示例#5
0
/*
 * Class:     bgcc_BaseProxy
 * Method:    getTicketId
 * Signature: (Ljava/lang/String;Lbgcc/IntHolder;ZLbgcc/Protocol;Lbgcc/Protocol;)I
 */
JNIEXPORT jint JNICALL Java_bgcc_BaseProxy_getTicketId
  (JNIEnv *env, jobject baseProxy, jstring fnName, jobject ticketIdHolder, jboolean last, jobject inProtocol, jobject outProtocol) {
      jclass baseProxyCls = env->GetObjectClass(baseProxy);
      jfieldID proxyAddressFid = env->GetFieldID(baseProxyCls, "proxyAddress", "J");

      BaseProxy* pBaseProxy = (BaseProxy*)env->GetLongField(baseProxy, proxyAddressFid);
      if (!pBaseProxy) {
          return -1;
      }

      const char* name_str = env->GetStringUTFChars(fnName, JNI_FALSE);
      int32_t ticketId = 0;

      jclass inProtocolCls = env->GetObjectClass(inProtocol);
      jfieldID inProtocolValueFid = env->GetFieldID(inProtocolCls, "protocolAddress", "J");
      SharedPointer<BinaryProtocol>* pInProtocol
          = (SharedPointer<BinaryProtocol>*)env->GetLongField(inProtocol, inProtocolValueFid);
      if (!pInProtocol || !pInProtocol->is_valid()) {
          return -1;
      }

      jclass outProtocolCls = env->GetObjectClass(outProtocol);
      jfieldID outProtocolValueFid = env->GetFieldID(outProtocolCls, "protocolAddress", "J");
      SharedPointer<IProtocol>* pOutProtocol
          = (SharedPointer<IProtocol>*)env->GetLongField(outProtocol, outProtocolValueFid);
      if (!pOutProtocol || !pOutProtocol->is_valid()) {
          return -1;
      }

      BGCC_TRACE("bgcc", "Before call C++ Interface __get_ticket_id");
	  pBaseProxy->__get_ticket_id(name_str, ticketId, last ? true : false, *pInProtocol, *pOutProtocol);
      BGCC_TRACE("bgcc", "End call C++ Interface __get_ticket_id: ticketId: %d", ticketId);

      jclass ticketIdHolderCls = env->GetObjectClass(ticketIdHolder);
      jfieldID ticketIdValueFid = env->GetFieldID(ticketIdHolderCls, "value", "I");
      env->SetIntField(ticketIdHolder, ticketIdValueFid, ticketId);

      env->ReleaseStringUTFChars(fnName, name_str);
      return 0;
  }
示例#6
0
	SharedPointer<ConnInfo> BaseProxy::create_Conn(){
        SharedPointer<bgcc::ClientSocket> client = 
			SharedPointer<bgcc::ClientSocket>(
					new ClientSocket(_serverinfo.getIP(),_serverinfo.getPort()));
        
		if (client.is_valid()) {
            if(client->open()==0){
                SharedPointer<BinaryProtocol> prot = 
					SharedPointer<BinaryProtocol>(new bgcc::BinaryProtocol(client));
                return SharedPointer<ConnInfo>(new ConnInfo(prot));
            }
        }
        return SharedPointer<ConnInfo>(NULL);
    }
示例#7
0
	SharedPointer<ConnInfo> SSLBaseProxy::create_Conn(){
        SharedPointer<bgcc::ClientSocket> client = 
			SharedPointer<bgcc::SSLClientSocket>(
					new SSLClientSocket(_serverinfo.getIP(),_serverinfo.getPort()));
        
		if (client.is_valid()) {
            if(client->open()==0){
                SharedPointer<BinaryProtocol> prot = 
					SharedPointer<BinaryProtocol>(new bgcc::BinaryProtocol(client));
                if(prot.is_valid()&& prot->getTransport().is_valid()){
                    int32_t tm=0;
                    if(get_property(PROXY_SEND_TIMEOUT, tm)){
                        SocketTool::set_sndtimeout(prot->getTransport()->id(), tm);
                    }
                    if(get_property(PROXY_RECV_TIMEOUT, tm)){
                        SocketTool::set_rcvtimeout(prot->getTransport()->id(), tm);
                    }
                }

                return SharedPointer<ConnInfo>(new ConnInfo(prot));
            }
        }
        return SharedPointer<ConnInfo>(NULL);
    }
示例#8
0
    void* call_back_thread_func(void* param) {
        BGCC_TRACE("bgcc", "enroll self");


        callback_thread_arg_t* arg = (callback_thread_arg_t*)param;
        std::string proxy_name = arg->proxy_name;
        std::string server_ip = arg->server_ip;
        int32_t server_port = arg->server_port;
        ServiceManager* service_manager = arg->service_manager;
        Semaphore* sema = arg->sema;

        SharedPointer<ClientSocket> connect;
        SharedPointer<BinaryProtocol> proto;

#ifndef _WIN32
        int32_t ep = epoll_create(1);
        struct epoll_event ee;
        struct epoll_event revents[1];

#endif
RECON:
        sema->signal();
        connect = SharedPointer<ClientSocket>(
                new(std::nothrow) ClientSocket(server_ip, server_port));

        connect->open();

        connect->set_recv_timeout(60*60*24*30);
        proto = SharedPointer<BinaryProtocol>(
                new(std::nothrow) BinaryProtocol(connect));
        int32_t ret = 0;

        ret = proto->writeMessageBegin("bgcc::BaseProcessor_enroll", "__enroll", bgcc::CALL, 0);
        if (ret < 0) {
            bgcc::TimeUtil::safe_sleep_s(1);
            goto RECON;
        }
        ret = proto->writeString(proxy_name);
        if (ret < 0) {
            bgcc::TimeUtil::safe_sleep_s(1);
            goto RECON;
        }
        ret = proto->writeMessageEnd();
        if (ret < 0) {
            bgcc::TimeUtil::safe_sleep_s(1);
            goto RECON;
        }
#ifndef _WIN32
        ee.data.fd = connect->get_socket();
        ee.events = EPOLLIN;
        epoll_ctl(ep, EPOLL_CTL_ADD, connect->get_socket(), &ee);
#endif
        while (true) {
#ifndef _WIN32
            int32_t nevent = epoll_wait(ep, revents, 1, -1);
            BGCC_TRACE("bgcc", "epoll_wait return %d", nevent);
            if (nevent >= 1) {
#endif
                char buffer[BUFSIZ];
                int32_t xxret;
                xxret = connect->read(buffer, 20);
                BGCC_TRACE("bgcc", "ret value read %d", xxret);
                if (0 != xxret) {
#ifndef _WIN32
                    epoll_ctl(ep, EPOLL_CTL_DEL, connect->get_socket(), &ee);
#endif
                    bgcc::TimeUtil::safe_sleep_s(1);
                    goto RECON;
                }
                int32_t body_len = (int32_t)ntohl(*(uint32_t*)(buffer +16));
                BGCC_TRACE("bgcc", "body size %d", body_len);
                char body[BUFSIZ];
                xxret = connect->read(body, body_len);
                BGCC_TRACE("bgcc", "body ret value read %d", xxret);
                if (0 != xxret) {
#ifndef _WIN32
                    epoll_ctl(ep, EPOLL_CTL_DEL, connect->get_socket(), &ee);
#endif
                    bgcc::TimeUtil::safe_sleep_s(1);
                    goto RECON;
                }
                int32_t processor_name_len = (int32_t)ntohl(*(uint32_t*)(body));
                std::string processor_name(body + 4, processor_name_len);
                SharedPointer<IProcessor> processor =
                    service_manager->get_service(processor_name);
                if (processor.is_valid()) {
                    processor->process(
                            body + 4 + processor_name_len,
                            body_len - 4 - processor_name_len,
                            proto);
                }

                /* added for handling unexist service*/
                else {
                    processor = service_manager->get_service("._baseservice_2012");
                    if (processor.is_valid()) {
                        SharedPointer<BinaryProtocol> bp(new BinaryProtocol(SharedPointer<ITransport>(NULL)));

                        bp->writeMessageBegin("xx", "__service_not_found", bgcc::CALL, 0);
                        bp->writeInt32(0);
                        bp->writeString("__service_not_found");
                        bp->writeBool(false);

                        void* data = NULL;
                        int32_t head_body_size;
                        NBDataBuffer* db = bp->get_data_buffer();
                        db->get_data(&data, head_body_size);
                        processor->process(
                                (char*)data + 20 + 4 + 2,
                                head_body_size - 20 - 4 - 2,
                                proto);

                    }
                }
#ifndef _WIN32
            }
#endif
        }

//#ifdef _WIN32
        return NULL;
//#endif

    }
示例#9
0
void bgcc::BusizProcessor::ProcessUser(ReadItem *pItem, const std::string &name, void *param, bool ssl, void* arg)
{
	BGCC_TRACE("bgcc", "...Enter User Process");
	char *p= pItem->item.data;
	static char buffer[MAX_DEFAULT_LEN]={0};
	int32_t buffer_size=MAX_DEFAULT_LEN;
	bgcc::ServiceManager* service_manager = NULL;
	bgcc::ThreadPool* thread_pool = NULL;
	SOCKET sock=INVALID_SOCKET;	

#ifndef _WIN32
	TaskAsso *pT=(TaskAsso*)param;
	EpollServer* pServer=(EpollServer*)pT->pServer;
	service_manager = pServer->get_service_manager();
	thread_pool = pServer->get_thread_pool();
	sock=pT->event.fd;
#endif

	SharedPointer<IProcessor> processor = service_manager->get_service(name);
	if(!processor.is_valid()){
		processor = service_manager->get_service(DEF_SERVICE);
		if(processor.is_valid()){
			p=NULL;
			if(Fake::fake_default_body(buffer, buffer_size)){
				p=buffer;
			
				BGCC_WARN("bgcc", "...Cannot find processor %s to use default service", 
					name.c_str());
			}
		}
	}

	if (processor.is_valid() && p) {
#ifndef _WIN32
		if (ssl) {
			SSLEventCallback::RemoveFD(pT->pLoop, sock, false);
		} else {
			EventCallback::RemoveFD(pT->pLoop, sock, false);
		}
#endif
		ServerPeerSocket* server_peer_socket = NULL;
		
		if (ssl) {
#ifndef _WIN32
            SSLEventCallbackArg* callbackArg = (SSLEventCallbackArg*)arg;
			server_peer_socket = new SSLServerPeerSocket(&(callbackArg->ssl), sock);
#endif
		} else {
			server_peer_socket = new ServerPeerSocket(sock);
		}

        if (!server_peer_socket->GetPeerInfo().is_valid()) {
            BGCC_WARN("bgcc", "Broken socket, fd=%d", sock);
            return;
        }

		SharedPointer<ITransport> trans(server_peer_socket);
		SharedPointer<IProtocol> proto(new BinaryProtocol(trans));
		SharedPointer<Runnable> task(new ServerTask(processor, p, 
					(p==pItem->item.data?pItem->item.nread:buffer_size), proto, param));

		if(!thread_pool->addTask(task)){
			BGCC_WARN("bgcc", "...Add Task Failed(fd=%d, processor=%s)", sock, name.c_str());
		}
	}
	else{
		BGCC_WARN("bgcc", "...Cannot find Any Processor do nothing");
	}
	BGCC_TRACE("bgcc", "...Leave User Process");
}
示例#10
0
void bgcc::EventCallback::DataCallback(EventLoop* el, SOCKET fd, void* arg)
{
	int32_t ret=0;
	char *p=NULL;

	bgcc::Mempool* mempool = bgcc::Mempool::get_instance();

	bgcc::ReadItem *pItem=&(Items[fd]);
	reading_item_t& item = pItem->item;
	p = item.head_buf;
	if(S_SIZE_READING == item.state){
		p = item.head_buf;
	}
	else if(S_DATA_READING == item.state){
		p = item.data;
	}

	BGCC_TRACE("bgcc", "Enter DataCallback(fd=%d)", fd);
	while (true){
		ret = recv(fd, p+item.nread, item.nexpected, 0);
		if(ret>0){
			item.nread += ret;
			item.nexpected -= ret;
			if (0 == item.nexpected) {
				if (S_SIZE_READING == item.state) {
					if (item.head_buf[0] != 'b'
							|| item.head_buf[1] != 'g'
							|| item.head_buf[2] != 'c'
							|| item.head_buf[3] != 'P') {
						BGCC_WARN("bgcc", "invalid bgcc header(fd=%d)", fd);
						pItem->err = -1;
						break;
					}
					item.state = S_DATA_READING;
					item.nexpected = BODY_LEN(p);

					if (item.nexpected < 0){
						BGCC_WARN("bgcc", "Message body length=%d too short, remove from epoll",
								item.nexpected);
						break;
					}
					else if(0==item.nexpected){
						BGCC_TRACE("bgcc", "Empty body Package");
						break;
					}

					item.data = (char*)mempool->get_mem_block(item.nexpected);
					p = item.data;
					item.nread = 0;
					continue;
				}
				else if (S_DATA_READING == item.state) {
					pItem->err=0;
					break;
				}
			}
		}
		else if (ret<0) {
			if (SocketTool::is_interrupt()) {
				continue;
			}
			else if (SocketTool::is_wouldblock()) {
				return;
			}
			else {
				pItem->err=BgccSockGetLastError();
				BGCC_WARN("bgcc", "Recv Failed. fd=%d errno=%d", 
						fd, pItem->err);
				break;
			}
		}
		else{
			pItem->err=-1;
			BGCC_TRACE("bgcc", "Recv Return 0. fd=%d ", fd);
			break;
		}
	}

	EpollServer *pArg=(EpollServer*)arg;
	TaskAsso *pT= (pArg?pArg->Tasks+fd:NULL);
	pT->pLoop=el;
	pT->pServer=(EpollServer*)arg;
	pT->pItem=pItem;
	PrepareEvent(pT->event, fd, arg);
	pItem->pTask=pT;

	int32_t todel=1;

        // save pItem->err and pItem->isEnroll
        // because pItem may be invalid after Process when err && isEnroll
        int32_t err = pItem->err;
        bool is_enroll = pItem->isEnroll;

	BusizProcessor::Process(pItem, pT, item.nread, &todel);

    if (err) {
        if (is_enroll) {//put_conn call RemoveFD, so here not to call RemoveFD
			if(todel){
				BGCC_WARN("bgcc", "Other Party is Closed Or Protocol Is Invalid, Force To Release fd=%d", fd);
				SharedPointer<BinaryProtocol> proto = SharedPointer<BinaryProtocol>(
					new BinaryProtocol( SharedPointer<ServerPeerSocket>(
							new ServerPeerSocket(fd)
							)));
				SharedPointer<ConnInfo> info=SharedPointer<ConnInfo>(
					new ConnInfo(proto, pItem)
					);
				if(proto.is_valid()&&info.is_valid()){
					bgcc::ConnectionManager::get_instance()->put_connection(pItem->item.memo, info, true);
				}
            }
		}
		else{
			BGCC_WARN("bgcc", "Other Party is Closed Or Protocol Is Invalid, Force To Release fd=%d", fd);
			RemoveFD(el,fd);
		}

	}
	BGCC_TRACE("bgcc", "Leave DataCallback(fd=%d)", fd);
}
示例#11
0
void bgcc::SSLEventCallback::DataCallback(EventLoop* el, SOCKET fd, void* arg)
{
	int32_t ret = 0;
	char* p = NULL;

	bgcc::Mempool* mempool = bgcc::Mempool::get_instance();
	struct SSLEventCallbackArg* callbackArg = (struct SSLEventCallbackArg*)arg;

	bgcc::ReadItem* pItem = &(Items[fd]);
	reading_item_t& item = pItem->item;
	p = item.head_buf;
	if (S_SIZE_READING == item.state) {
		p = item.head_buf;
	} else if (S_DATA_READING == item.state) {
		p = item.data;
	}

	BGCC_TRACE("bgcc", "Enter SSL DataCallback(fd=%d)", fd);

	if (!callbackArg->ssl) {
		BGCC_TRACE("bgcc", "callbackArg->ssl is NULL, we should not be here.");
		TimeUtil::safe_sleep_ms(0);
		BGCC_TRACE("bgcc", "Leave SSL DataCallback(fd=%d)", fd);
		return;
	}

	bool do_while = true;

	while (true && do_while) {
		ret = SSL_read(callbackArg->ssl, p + item.nread, item.nexpected);
		switch(SSL_get_error(callbackArg->ssl, ret)) {
			case SSL_ERROR_NONE:
				item.nread += ret;
				item.nexpected -= ret;
				if (0 == item.nexpected) {
					if (S_SIZE_READING == item.state) {
						if (item.head_buf[0] != 'b'
								|| item.head_buf[1] != 'g'
								|| item.head_buf[2] != 'c'
								|| item.head_buf[3] != 'P') {
							BGCC_WARN("bgcc", "invalid bgcc header(fd=%d)", fd);
							pItem->err = -1;
							do_while = false;
							break;
						}
						item.state = S_DATA_READING;
						item.nexpected = BODY_LEN(p);

						if (item.nexpected < 0) {
							BGCC_WARN("bgcc", "Message body length=%d too short, remove from epoll", item.nexpected);
							do_while = false;
							break;
						} else if (0 == item.nexpected) {
							BGCC_TRACE("bgcc", "Empty body Package");
							do_while = false;
							break;
						}

						item.data = (char*)mempool->get_mem_block(item.nexpected);
						p = item.data;
						item.nread = 0;
						continue;
					} else if (S_DATA_READING == item.state) {
						pItem->err = 0;
						do_while = false;
						break;
					}
				}
				continue;
			case SSL_ERROR_WANT_READ:
			case SSL_ERROR_WANT_WRITE:
				return;
			default:
				pItem->err = -1;
				do_while = false;
				break;

		}
	}

	SSLEpollServer* pArg = (SSLEpollServer*)callbackArg->arg;
	TaskAsso* pT = pArg ? pArg->Tasks+fd : NULL;
	pT->pLoop = el;
	pT->pServer = pArg;
	pT->pItem = pItem;
	
	PrepareEvent(pT->event, fd, arg);
	pItem->pTask = pT;

	int32_t todel = 1;
	BusizProcessor::Process(pItem, pT, item.nread, &todel, true, arg);

	if (pItem->err) {
		SSL_shutdown(callbackArg->ssl);
		BGCC_DEBUG("bgcc", "Memory SSL free: %p", callbackArg->ssl);
		SSL_free(callbackArg->ssl);
		callbackArg->ssl = NULL;

		if (pItem->isEnroll) {
			if(todel){
				BGCC_WARN("bgcc", "Other Party is Closed Or Protocol Is Invalid, Force To Release fd=%d", fd);
				SharedPointer<BinaryProtocol> proto = SharedPointer<BinaryProtocol>(
					new BinaryProtocol( SharedPointer<ServerPeerSocket>(
							new ServerPeerSocket(fd)
							)));
				SharedPointer<ConnInfo> info=SharedPointer<ConnInfo>(
					new ConnInfo(proto, pItem)
					);
				if(proto.is_valid()&&info.is_valid()){
					bgcc::ConnectionManager::get_instance()->put_connection(pItem->item.memo, info, true);
				}
			}
		} else {
			BGCC_WARN("bgcc", "Other Party is Closed Or Protocol Is Invalid, Force To Release fd=%d", fd);
			RemoveFD(el,fd);
		}
	}

	BGCC_TRACE("bgcc", "Leave SSL DataCallback(fd=%d)", fd);
}