nlsCppSdk/framework/common/nlsClientImpl.cpp (669 lines of code) (raw):

/* * Copyright 2021 Alibaba Group Holding Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef _MSC_VER #include <unistd.h> #endif #include "SSLconnect.h" #include "connectNode.h" #include "da/dialogAssistantRequest.h" #include "fss/flowingSynthesizerRequest.h" #include "nlog.h" #include "nlsClientImpl.h" #include "nlsEventNetWork.h" #include "sr/speechRecognizerRequest.h" #include "st/speechTranscriberRequest.h" #include "sy/speechSynthesizerRequest.h" #include "text_utils.h" #include "utility.h" #ifdef ENABLE_VIPSERVER //引入VipClientApi相关的头文件 #include "iphost.h" #include "option.h" #include "vipclient.h" #include "vipclient_helper.hpp" using namespace middleware::vipclient; #endif namespace AlibabaNls { bool NlsClientImpl::_isInitializeSSL = false; bool NlsClientImpl::_isInitializeThread = false; #ifdef ENABLE_VIPSERVER bool NlsClientImpl::_isInitalizeVsClient = false; pthread_mutex_t _mtx = PTHREAD_MUTEX_INITIALIZER; #endif NlsClientImpl::NlsClientImpl(bool sslInitial) : _nodeManager(NULL), _aiFamily(), _directHostIp(), _enableSysGetAddr(false), #ifdef ENABLE_PRECONNECTED_POO _maxPreconnectedNumber(0), _preconnectedTimeoutMs(15000), _prerequestedTimeoutMs(75000), #endif _syncCallTimeoutMs(0) { strncpy(_aiFamily, "AF_INET", 16); // init openssl if (sslInitial) { if (!_isInitializeSSL) { SSLconnect::init(); _isInitializeSSL = sslInitial; } } _nodeManager = new NlsNodeManager(); #if defined(_MSC_VER) _mtxReleaseRequestGuard = CreateMutex(NULL, FALSE, NULL); #else pthread_mutex_init(&_mtxReleaseRequestGuard, NULL); #endif #ifdef ENABLE_VIPSERVER VipClientApi::CreateApi(); #endif } NlsClientImpl::~NlsClientImpl() { #if defined(_MSC_VER) CloseHandle(_mtxReleaseRequestGuard); #else pthread_mutex_destroy(&_mtxReleaseRequestGuard); #endif } void NlsClientImpl::releaseInstanceImpl() { LOG_INFO("Release NlsClientImpl instance:%p.", this); if (_isInitializeThread) { if (NlsEventNetWork::_eventClient != NULL) { #ifdef ENABLE_PRECONNECTED_POOL NlsEventNetWork::_eventClient->destroyPreconnectedPool(); #endif NlsEventNetWork::_eventClient->destroyEventNetWork(); delete NlsEventNetWork::_eventClient; NlsEventNetWork::_eventClient = NULL; } _isInitializeThread = false; } if (_isInitializeSSL) { SSLconnect::destroy(); _isInitializeSSL = false; } #ifdef ENABLE_VIPSERVER LOG_INFO("destroy VipClient."); if (_isInitalizeVsClient) { VipClientApi::UnInit(); _isInitalizeVsClient = false; } VipClientApi::DestoryApi(); #endif /* find NlsClientImp in map and erase it */ int ret = _nodeManager->removeInstanceFromInfo(this); if (ret != Success) { LOG_ERROR("removeInstanceFromInfo instance(%p) failed, ret:%d", this, ret); return; } delete _nodeManager; _nodeManager = NULL; LOG_INFO("destroy log instance."); utility::NlsLog::destroyLogInstance(); // donnot LOG_XXX after here } NlsNodeManager *NlsClientImpl::getNodeManger() { return _nodeManager; } void NlsClientImpl::setAddrInFamilyImpl(const char *aiFamily) { if (aiFamily != NULL && (strncmp(aiFamily, "AF_INET", 16) == 0 || strncmp(aiFamily, "AF_INET6", 16) == 0 || strncmp(aiFamily, "AF_UNSPEC", 16) == 0)) { memset(_aiFamily, 0, 16); strncpy(_aiFamily, aiFamily, 16); } } void NlsClientImpl::setUseSysGetAddrInfoImpl(bool enable) { _enableSysGetAddr = enable; } void NlsClientImpl::setSyncCallTimeoutImpl(unsigned int timeout_ms) { _syncCallTimeoutMs = timeout_ms; } #ifdef ENABLE_PRECONNECTED_POOL void NlsClientImpl::setPreconnectedPool(unsigned int maxNumber, unsigned int timeoutMs, unsigned int requestTimeoutMs) { _maxPreconnectedNumber = maxNumber; _preconnectedTimeoutMs = timeoutMs >= 23000 ? 23000 : timeoutMs; _prerequestedTimeoutMs = requestTimeoutMs >= 8000 ? 8000 : requestTimeoutMs; } #endif void NlsClientImpl::setDirectHostImpl(const char *ip) { memset(_directHostIp, 0, 64); if (ip) { strncpy(_directHostIp, ip, 64); } } void NlsClientImpl::startWorkThreadImpl(int threadsNumber) { if (NlsEventNetWork::_eventClient == NULL) { NlsEventNetWork::_eventClient = new NlsEventNetWork(); } if (!_isInitializeThread) { NlsEventNetWork::_eventClient->initEventNetWork( this, threadsNumber, _aiFamily, _directHostIp, _enableSysGetAddr, _syncCallTimeoutMs); _isInitializeThread = true; #ifdef ENABLE_PRECONNECTED_POOL if (_maxPreconnectedNumber > 0) { NlsEventNetWork::_eventClient->initPreconnectedPool( _maxPreconnectedNumber, _preconnectedTimeoutMs, _prerequestedTimeoutMs); } #endif } } int NlsClientImpl::setLogConfigImpl(const char *logOutputFile, const LogLevel logLevel, unsigned int logFileSize, unsigned int logFileNum, LogCallbackMethod logCallback) { if (logLevel < LogError || logLevel > LogDebug) { return -(InvalidLogLevel); } if (logFileNum < 1) { return -(InvalidLogFileNum); } utility::NlsLog::getInstance()->logConfig( logOutputFile, logLevel, logFileSize, logFileNum, logCallback); return Success; } SpeechRecognizerRequest *NlsClientImpl::createRecognizerRequestImpl( const char *sdkName, bool isLongConnection) { SpeechRecognizerRequest *request = new SpeechRecognizerRequest(sdkName, isLongConnection); if (request) { int ret = _nodeManager->addRequestIntoInfoWithInstance((void *)request, (void *)this); if (ret != Success) { LOG_ERROR( "Request(%p) checkRequestWithInstance failed(%d), this request has " "released.", request, ret); delete request; request = NULL; } } return request; } void NlsClientImpl::releaseRecognizerRequestImpl( SpeechRecognizerRequest *request) { if (request) { int ret = Success; /* check this request belong to this NlsClientImpl */ ret = _nodeManager->checkRequestWithInstance((void *)request, (void *)this); if (ret != Success) { LOG_ERROR("Request(%p) checkRequestWithInstance failed.", request); return; } ConnectNode *node = request->getConnectNode(); if (node && node->getExitStatus() == ExitInvalid && node->getConnectNodeStatus() != NodeClosed) { LOG_DEBUG( "Request(%p) Node(%p) invoke cancel by releaseRecognizerRequest.", request, node); request->cancel(); } releaseRequest(request); } } SpeechTranscriberRequest *NlsClientImpl::createTranscriberRequestImpl( const char *sdkName, bool isLongConnection) { SpeechTranscriberRequest *request = new SpeechTranscriberRequest(sdkName, isLongConnection); if (request) { int ret = _nodeManager->addRequestIntoInfoWithInstance((void *)request, (void *)this); if (ret != Success) { LOG_ERROR( "Request(%p) checkRequestWithInstance failed(%d), this request has " "released.", request, ret); delete request; request = NULL; } } return request; } void NlsClientImpl::releaseTranscriberRequestImpl( SpeechTranscriberRequest *request) { if (request) { int ret = Success; /* check this request belong to this NlsClientImpl */ ret = _nodeManager->checkRequestWithInstance((void *)request, (void *)this); if (ret != Success) { LOG_ERROR("Request(%p) checkRequestWithInstance failed.", request); return; } ConnectNode *node = request->getConnectNode(); if (node && node->getExitStatus() == ExitInvalid && node->getConnectNodeStatus() != NodeClosed) { LOG_DEBUG( "Request(%p) Node(%p) invoke cancel by releaseTranscriberRequest.", request, node); request->cancel(); } releaseRequest(request); } } SpeechSynthesizerRequest *NlsClientImpl::createSynthesizerRequestImpl( TtsVersion version, const char *sdkName, bool isLongConnection) { SpeechSynthesizerRequest *request = new SpeechSynthesizerRequest((int)version, sdkName, isLongConnection); if (request) { int ret = _nodeManager->addRequestIntoInfoWithInstance((void *)request, (void *)this); if (ret != Success) { LOG_ERROR( "Request(%p) checkRequestWithInstance failed(%d), this request has " "released.", request, ret); delete request; request = NULL; } } return request; } void NlsClientImpl::releaseSynthesizerRequestImpl( SpeechSynthesizerRequest *request) { if (request) { int ret = Success; /* check this request belong to this NlsClientImpl */ ret = _nodeManager->checkRequestWithInstance((void *)request, (void *)this); if (ret != Success) { LOG_ERROR("Request(%p) Node(%p) is invalid.", request, request->getConnectNode()); return; } ConnectNode *node = request->getConnectNode(); if (node && node->getExitStatus() == ExitInvalid && node->getConnectNodeStatus() != NodeClosed) { LOG_DEBUG( "Request(%p) Node(%p) invoke cancel by releaseSynthesizerRequest.", request, node); request->cancel(); } releaseRequest(request); } } DialogAssistantRequest *NlsClientImpl::createDialogAssistantRequestImpl( DaVersion version, const char *sdkName, bool isLongConnection) { DialogAssistantRequest *request = new DialogAssistantRequest((int)version, sdkName, isLongConnection); if (request) { int ret = _nodeManager->addRequestIntoInfoWithInstance((void *)request, (void *)this); if (ret != Success) { LOG_ERROR( "Request(%p) checkRequestWithInstance failed(%d), this request has " "released.", request, ret); delete request; request = NULL; } } return request; } void NlsClientImpl::releaseDialogAssistantRequestImpl( DialogAssistantRequest *request) { if (request) { int ret = Success; /* check this request belong to this NlsClientImpl */ ret = _nodeManager->checkRequestWithInstance((void *)request, (void *)this); if (ret != Success) { LOG_ERROR("request(%p) is invalid.", request); return; } ConnectNode *node = request->getConnectNode(); if (node && request->getConnectNode()->getExitStatus() == ExitInvalid) { request->cancel(); } releaseRequest(request); } } FlowingSynthesizerRequest *NlsClientImpl::createFlowingSynthesizerRequestImpl( const char *sdkName, bool isLongConnection) { FlowingSynthesizerRequest *request = new FlowingSynthesizerRequest(sdkName, isLongConnection); if (request) { int ret = _nodeManager->addRequestIntoInfoWithInstance((void *)request, (void *)this); if (ret != Success) { LOG_ERROR( "Request(%p) checkRequestWithInstance failed(%d), this request has " "released.", request, ret); delete request; request = NULL; } } return request; } void NlsClientImpl::releaseFlowingSynthesizerRequestImpl( FlowingSynthesizerRequest *request) { if (request) { int ret = Success; /* check this request belong to this NlsClientImpl */ ret = _nodeManager->checkRequestWithInstance((void *)request, (void *)this); if (ret != Success) { LOG_ERROR("Request(%p) is invalid.", request); return; } ConnectNode *node = request->getConnectNode(); if (node && node->getExitStatus() == ExitInvalid && node->getConnectNodeStatus() != NodeClosed) { LOG_DEBUG( "Request(%p) Node(%p) invoke cancel by " "releaseFlowingSynthesizerRequest.", request, node); request->cancel(); } releaseRequest(request); } } void NlsClientImpl::releaseRequest(INlsRequest *request) { uint64_t timewait_start, timewait_end; timewait_start = utility::TextUtils::GetTimestampMs(); if (request == NULL) { LOG_ERROR("Input request is nullptr, you have destroyed request!"); return; } if (request->getConnectNode() == NULL) { LOG_ERROR("The node in request(%p) is nullptr, you have destroyed request!", request); return; } int status = NodeStatusInvalid; int ret = _nodeManager->checkRequestExist(request, &status); if (ret != Success) { LOG_ERROR("Request(%p) checkRequestExist0 failed, %d.", request, ret); return; } /* 准备移出request, 上锁保护, 防止其他线程也同时在释放 */ bool release_lock_ret = true; NlsClientImpl *cur_instance = request->getConnectNode()->getInstance(); if (cur_instance != NULL) { #ifdef ENABLE_NLS_DEBUG_2 LOG_DEBUG("Request(%p) Node(%p) trylock with %p.", request, request->getConnectNode(), &cur_instance->_mtxReleaseRequestGuard); #endif MUTEX_TRY_LOCK_WITH_TAG(cur_instance->_mtxReleaseRequestGuard, 2000, release_lock_ret, request); if (!release_lock_ret) { LOG_ERROR("Request(%p) lock destroy failed, deadlock has occurred", request); } } else { LOG_INFO("Request(%p) just only created ...", request); release_lock_ret = false; } ret = _nodeManager->checkRequestExist(request, &status); if (ret != Success) { LOG_ERROR("Request(%p) checkRequestExist1 failed, %d.", request, ret); if (release_lock_ret) { MUTEX_UNLOCK_WITH_TAG(cur_instance->_mtxReleaseRequestGuard, request); } return; } request->getConnectNode()->_releasingFlag = true; LOG_INFO("Begin release, request(%p) node(%p) node status:%s exit status:%s.", request, request->getConnectNode(), request->getConnectNode()->getConnectNodeStatusString().c_str(), request->getConnectNode()->getExitStatusString().c_str()); evutil_socket_t curSocketFd = request->getConnectNode()->getSocketFd(); SSLconnect *curSslHandle = request->getConnectNode()->getSslHandle(); SSLconnect *curNativeSslHandle = request->getConnectNode()->getNativeSslHandle(); NlsType type = request->getRequestParam()->_mode; INlsRequest *curRequest = request; bool sslInConnectedPool = false; bool oriRequestIsAbnormal = false; bool requestInPool = false; #ifdef ENABLE_PRECONNECTED_POOL if (request->getConnectNode()->isUsingPreconnection() && NlsEventNetWork::_eventClient && NlsEventNetWork::_eventClient->getPreconnectedPool()) { if (NlsEventNetWork::_eventClient->getPreconnectedPool()->sslBelongToPool( request, type, oriRequestIsAbnormal, requestInPool)) { sslInConnectedPool = true; if (oriRequestIsAbnormal) { LOG_WARN( "Request(%p) node(%p) has stored in ConnectedPool, with %s " "usePreconnection and SSL(%p), native SSL(%p). But current request " "is abnormal.", request, request->getConnectNode(), request->getConnectNode()->isUsingPreconnection() ? "enable" : "disable", request->getConnectNode()->getSslHandle(), request->getConnectNode()->getNativeSslHandle()); } else { LOG_DEBUG( "Request(%p) node(%p) has stored in ConnectedPool, with %s " "usePreconnection and SSL(%p), native SSL(%p).", request, request->getConnectNode(), request->getConnectNode()->isUsingPreconnection() ? "enable" : "disable", request->getConnectNode()->getSslHandle(), request->getConnectNode()->getNativeSslHandle()); } } else { LOG_DEBUG( "Request(%p) node(%p) not stored in ConnectedPool, with %s " "usePreconnection and SSL(%p), native SSL(%p).", request, request->getConnectNode(), request->getConnectNode()->isUsingPreconnection() ? "enable" : "disable", request->getConnectNode()->getSslHandle(), request->getConnectNode()->getNativeSslHandle()); } } #endif request->getConnectNode()->delAllEvents(); if (!sslInConnectedPool) { request->getConnectNode()->updateDestroyStatus(); } int index = request->getConnectNode()->getPoolIndex(); ret = _nodeManager->removeRequestFromInfo(request, false); if (ret == Success) { #ifdef ENABLE_PRECONNECTED_POOL // if (sslInConnectedPool) { // if (oriRequestIsAbnormal) { // LOG_INFO( // "Request(%p) Node(%p) with SSL handle(%p) socketFd(%d) has stored // " "in ConnectedPool, and orignal request is abnormal, should // delete " "itself.", request, request->getConnectNode(), // curSslHandle, curSocketFd); // delete request; // } // } else { // LOG_DEBUG( // "Request(%p) Node(%p) with SSL handle(%p) socketFd(%d) is not // stored " "in ConnectedPool, should delete.", request, // request->getConnectNode(), curSslHandle, curSocketFd); // delete request; // } if (requestInPool) { LOG_INFO( "Request(%p) Node(%p) with SSL handle(%p) socketFd(%d) has stored " "in ConnectedPool, and it is orignal request, should delete " "itself later, not here.", request, request->getConnectNode(), curSslHandle, curSocketFd); } else { LOG_DEBUG( "Request(%p) Node(%p) with SSL handle(%p) socketFd(%d) did not " "stored " "in ConnectedPool, delete here.", request, request->getConnectNode(), curSslHandle, curSocketFd); delete request; } #else delete request; #endif } else { LOG_ERROR("Release request(%p) is invalid, skip ...", request); } request = NULL; if (sslInConnectedPool) { if (oriRequestIsAbnormal) { LOG_INFO( "Request(%p) SSL(%p) and socketFd(%d) index(%d) has stored in " "ConnectedPool, and orignal request is abnormal, should delete this " "orignal request in ConnectedPool.", curRequest, curSslHandle, curSocketFd, index); #ifdef ENABLE_PRECONNECTED_POOL if (NlsEventNetWork::_eventClient && NlsEventNetWork::_eventClient->getPreconnectedPool()) { NlsEventNetWork::_eventClient->getPreconnectedPool() ->deletePreNodeBySSL(curSslHandle, type); } #endif } else { LOG_DEBUG( "Request(%p) SSL(%p) and socketFd(%d) index(%d) has stored in " "ConnectedPool, " "and will release later " "in " "ConnectedPool.", curRequest, curSslHandle, curSocketFd, index); #ifdef ENABLE_PRECONNECTED_POOL if (NlsEventNetWork::_eventClient && NlsEventNetWork::_eventClient->getPreconnectedPool()) { NlsEventNetWork::_eventClient->getPreconnectedPool()->finishPushPreNode( type, curSocketFd, curSslHandle, index, curRequest); } #endif } } else { LOG_DEBUG( "Request(%p) SSL(%p) NativeSSL(%p) and socketFd(%d) index(%d) not " "stored in ConnectedPool, " "and remove this request from ConnectedPool.", curRequest, curSslHandle, curNativeSslHandle, curSocketFd, index); #ifdef ENABLE_PRECONNECTED_POOL if (NlsEventNetWork::_eventClient && NlsEventNetWork::_eventClient->getPreconnectedPool()) { NlsEventNetWork::_eventClient->getPreconnectedPool() ->deletePreNodeByRequest(curRequest, type); } #endif } if (release_lock_ret) { MUTEX_UNLOCK_WITH_TAG(cur_instance->_mtxReleaseRequestGuard, curRequest); } #ifdef ENABLE_NLS_DEBUG_2 else { LOG_WARN("_mtxReleaseRequestGuard isnot unlock."); } LOG_DEBUG("Release request(%p) done.", curRequest); #endif timewait_end = utility::TextUtils::GetTimestampMs(); if (timewait_end - timewait_start > 50) { LOG_ERROR("Release request(%p) excessive latency:%llums", curRequest, timewait_end - timewait_start); } return; } #if defined(__linux__) int NlsClientImpl::vipServerListGetUrlImpl( const std::string &vipServerDomainList, const std::string &targetDomain, std::string &url) { #ifdef ENABLE_VIPSERVER std::string domainPattern = ","; std::string portPattern = ":"; std::string vipServerBuff, serverIp, serverPort; int port = VipServerPort; LOG_DEBUG("vipServerDomainList: %s.", vipServerDomainList.c_str()); size_t domainStart = 0, domainSeek = vipServerDomainList.find_first_of(domainPattern, 0); size_t portSeek = 0; while (domainSeek != vipServerDomainList.npos) { if (domainStart != domainSeek) { vipServerBuff = vipServerDomainList.substr(domainStart, domainSeek - domainStart); LOG_DEBUG("vipServerBuff: %s", vipServerBuff.c_str()); portSeek = vipServerBuff.find_first_of(portPattern, 0); if (portSeek != vipServerBuff.npos) { serverIp = vipServerBuff.substr(0, portSeek); serverPort = vipServerBuff.substr(portSeek + 1, vipServerBuff.length() - portSeek); if (!serverPort.empty()) { port = atoi(serverPort.c_str()); } } else { serverIp = vipServerBuff; } // Get ip if (Success == vipServerGetIp(serverIp, port, targetDomain, url)) { LOG_DEBUG("vipServerGetIp successed:%s.", url.c_str()); return Success; } else { MUTEX_LOCK(_mtx); _isInitalizeVsClient = false; VipClientApi::UnInit(); MUTEX_UNLOCK(_mtx); } } domainStart = domainSeek + 1; domainSeek = vipServerDomainList.find_first_of(domainPattern, domainStart); } LOG_DEBUG("Last vipServerBuff: %s", vipServerBuff.c_str()); port = VipServerPort; if (!vipServerDomainList.substr(domainStart).empty()) { vipServerBuff = vipServerDomainList.substr(domainStart); portSeek = vipServerBuff.find_first_of(portPattern, 0); if (portSeek != vipServerBuff.npos) { serverIp = vipServerBuff.substr(0, portSeek); serverPort = vipServerBuff.substr(portSeek + 1, vipServerBuff.size() - portSeek); if (!serverPort.empty()) { port = atoi(serverPort.c_str()); } } else { serverIp = vipServerBuff; } // Get ip return vipServerGetIp(serverIp, port, targetDomain, url); } #else LOG_WARN("Donnot enable VipServer."); #endif // ENABLE_VIPSERVER return Success; } int NlsClientImpl::vipServerGetIp(const std::string &vipServerDomain, const int vipServerPort, const std::string &targetDomain, std::string &url) { #ifdef ENABLE_VIPSERVER if (vipServerDomain.empty() || targetDomain.empty() || vipServerPort < 0) { LOG_ERROR("vipServerGetIp::Input Param error ..."); return -(InvalidInputParam); } int tmpPort = vipServerPort; char buff[512] = {0}; if (tmpPort == 0) { tmpPort = VipServerPort; } if (snprintf(buff, 512, "%s:%d", vipServerDomain.c_str(), tmpPort) < 0) { return -(InvalidInputParam); } LOG_DEBUG("vipServerGetIp: %s.", buff); MUTEX_LOCK(_mtx); if (!_isInitalizeVsClient) { Option option; //设置日志最大大小(可选) option.set_max_log_size(10LL * 1024 * 1024); //初始化 // buff: vipserver顶级域名 if (!VipClientApi::Init(buff, option)) { LOG_ERROR("Init failed top domain:%s errno:%d errstr:%s.", buff, VipClientApi::Errno(), VipClientApi::Errstr()); MUTEX_UNLOCK(_mtx); return -(VipClientInitFailed); } else { _isInitalizeVsClient = true; LOG_INFO("VipClientApi::Init Successed ..."); } } MUTEX_UNLOCK(_mtx); std::string ip; IPHost host; // 同步获取域名(targetDomain)下的一个IPHost if (VipClientApi::QueryIp(targetDomain.c_str(), &host, 5 * 1000)) { std::string host_str = helper::ToString(host); LOG_DEBUG("get domain ip ok %s, iphost:%s", targetDomain.c_str(), host_str.c_str()); } else { LOG_ERROR("Target domain:%s QueryIp::Failed. errno:%d errstr:%s.", targetDomain.c_str(), VipClientApi::Errno(), VipClientApi::Errstr()); } //同步获取IP列表,2000ms超时 IPHost iphost; if (VipClientApi::QueryIp(targetDomain.c_str(), &iphost, 5 * 1000)) { ip = iphost.ip(); int port = iphost.port(); LOG_DEBUG("valid ip %s %d", iphost.ip(), iphost.port()); char buffer[256] = {0}; if (snprintf(buffer, 256, "ws://%s:%d/ws/v1", ip.c_str(), port) < 0) { LOG_ERROR("ERROR : Merge host Failed."); return -(VipClientMergeHostFailed); } url = buffer; LOG_DEBUG("targetUrl: %s", url.c_str()); return Success; } else { LOG_ERROR("ERROR: QueryIp Failed. errno:%d errstr:%s.", VipClientApi::Errno(), VipClientApi::Errstr()); return -(VipClientQueryIpFailed); } #else LOG_WARN("Donnot enable VipServer."); #endif // ENABLE_VIPSERVER return Success; } #endif } // namespace AlibabaNls