RsslRet processActiveChannel(ChannelHandler *pChanHandler, ChannelInfo *pChannelInfo) { ProviderThread *pProviderThread = (ProviderThread*)pChanHandler->pUserSpec; ProviderSession *pProvSession = (ProviderSession*)pChannelInfo->pUserSpec; RsslRet ret; RsslError error; RsslChannelInfo channelInfo; RsslUInt32 count; if (niProvPerfConfig.highWaterMark > 0) { if (rsslIoctl(pChannelInfo->pChannel, RSSL_HIGH_WATER_MARK, &niProvPerfConfig.highWaterMark, &error) != RSSL_RET_SUCCESS) { printf("rsslIoctl() of RSSL_HIGH_WATER_MARK failed <%s>\n", error.text); exit(-1); } } if ((ret = rsslGetChannelInfo(pChannelInfo->pChannel, &channelInfo, &error)) != RSSL_RET_SUCCESS) { printf("rsslGetChannelInfo() failed: %d\n", ret); return 0; } printf( "Channel %d active. Channel Info:\n" " maxFragmentSize: %u\n" " maxOutputBuffers: %u\n" " guaranteedOutputBuffers: %u\n" " numInputBuffers: %u\n" " pingTimeout: %u\n" " clientToServerPings: %s\n" " serverToClientPings: %s\n" " sysSendBufSize: %u\n" " sysSendBufSize: %u\n" " compressionType: %s\n" " compressionThreshold: %u\n" " ComponentInfo: ", pChannelInfo->pChannel->socketId, channelInfo.maxFragmentSize, channelInfo.maxOutputBuffers, channelInfo.guaranteedOutputBuffers, channelInfo.numInputBuffers, channelInfo.pingTimeout, channelInfo.clientToServerPings == RSSL_TRUE ? "true" : "false", channelInfo.serverToClientPings == RSSL_TRUE ? "true" : "false", channelInfo.sysSendBufSize, channelInfo.sysRecvBufSize, channelInfo.compressionType == RSSL_COMP_ZLIB ? "zlib" : "none", channelInfo.compressionThreshold ); if (channelInfo.componentInfoCount == 0) printf("(No component info)"); else for(count = 0; count < channelInfo.componentInfoCount; ++count) { printf("%.*s", channelInfo.componentInfo[count]->componentVersion.length, channelInfo.componentInfo[count]->componentVersion.data); if (count < channelInfo.componentInfoCount - 1) printf(", "); } printf ("\n\n"); /* Check that we can successfully pack, if packing messages. */ if (providerThreadConfig.totalBuffersPerPack > 1 && providerThreadConfig.packingBufferLength > channelInfo.maxFragmentSize) { printf("Error(Channel %d): MaxFragmentSize %u is too small for packing buffer size %u\n", pChannelInfo->pChannel->socketId, channelInfo.maxFragmentSize, providerThreadConfig.packingBufferLength); exit(-1); } if (ret = (printEstimatedMsgSizes(pProviderThread, pProvSession)) != RSSL_RET_SUCCESS) return RSSL_RET_FAILURE; pProvSession->timeActivated = getTimeNano(); /* Send Login Request */ ret = sendLoginRequest(pChanHandler, pChannelInfo, 1, &error); if (ret < RSSL_RET_SUCCESS) { printf("sendLoginRequest() failed: %d\n", ret); exit(-1); } else if (ret > RSSL_RET_SUCCESS) { /* Need to flush */ providerThreadRequestChannelFlush(pProviderThread, pChannelInfo); } return RSSL_RET_SUCCESS; }
RsslRet processMsg(ChannelHandler *pChannelHandler, ChannelInfo* pChannelInfo, RsslBuffer* pBuffer) { RsslRet ret = RSSL_RET_SUCCESS; RsslMsg msg = RSSL_INIT_MSG; RsslDecodeIterator dIter; ProviderThread *pProvThread = (ProviderThread*)pChannelHandler->pUserSpec; RsslChannel *pChannel = pChannelInfo->pChannel; /* clear decode iterator */ rsslClearDecodeIterator(&dIter); /* set version info */ rsslSetDecodeIteratorRWFVersion(&dIter, pChannel->majorVersion, pChannel->minorVersion); rsslSetDecodeIteratorBuffer(&dIter, pBuffer); ret = rsslDecodeMsg(&dIter, &msg); if (ret != RSSL_RET_SUCCESS) { printf("\nrsslDecodeMsg(): Error %d on SessionData fd=%d Size %d \n", ret, pChannel->socketId, pBuffer->length); cleanUpAndExit(); } switch ( msg.msgBase.domainType ) { case RSSL_DMT_LOGIN: ret = processLoginRequest(pChannelHandler, pChannelInfo, &msg, &dIter); break; case RSSL_DMT_SOURCE: ret = processDirectoryRequest(pChannelHandler, pChannelInfo, &msg, &dIter); break; case RSSL_DMT_DICTIONARY: ret = processDictionaryRequest(pChannelHandler, pChannelInfo, &msg, &dIter); break; case RSSL_DMT_MARKET_PRICE: if (xmlMsgDataHasMarketPrice) ret = processItemRequest(pProvThread, (ProviderSession*)pChannelInfo->pUserSpec, &msg, &dIter); else ret = sendItemRequestReject(pProvThread, (ProviderSession*)pChannelInfo->pUserSpec, msg.msgBase.streamId, msg.msgBase.domainType, DOMAIN_NOT_SUPPORTED); break; case RSSL_DMT_MARKET_BY_ORDER: if (xmlMsgDataHasMarketByOrder) ret = processItemRequest(pProvThread, (ProviderSession*)pChannelInfo->pUserSpec, &msg, &dIter); else ret = sendItemRequestReject(pProvThread, (ProviderSession*)pChannelInfo->pUserSpec, msg.msgBase.streamId, msg.msgBase.domainType, DOMAIN_NOT_SUPPORTED); break; default: ret = sendItemRequestReject(pProvThread, (ProviderSession*)pChannelInfo->pUserSpec, msg.msgBase.streamId, msg.msgBase.domainType, DOMAIN_NOT_SUPPORTED); break; } if (ret < RSSL_RET_SUCCESS) { printf("Failed to process request from domain %d: %d\n", msg.msgBase.domainType, ret); } else if (ret > RSSL_RET_SUCCESS) { /* The function sent a message and indicated that we need to flush. */ providerThreadRequestChannelFlush(pProvThread, pChannelInfo); } return ret; }
RsslRet processMsg(ChannelHandler *pChannelHandler, ChannelInfo* pChannelInfo, RsslBuffer* pBuffer) { RsslRet ret = RSSL_RET_SUCCESS; RsslMsg msg = RSSL_INIT_MSG; RsslDecodeIterator dIter; RsslChannel *chnl = pChannelInfo->pChannel; ProviderThread *pProviderThread = (ProviderThread*)pChannelHandler->pUserSpec; /* clear decode iterator */ rsslClearDecodeIterator(&dIter); /* set version info */ rsslSetDecodeIteratorRWFVersion(&dIter, chnl->majorVersion, chnl->minorVersion); rsslSetDecodeIteratorBuffer(&dIter, pBuffer); ret = rsslDecodeMsg(&dIter, &msg); if (ret != RSSL_RET_SUCCESS) { printf("\nrsslDecodeMsg(): Error %d on SessionData fd=%d Size %d \n", ret, chnl->socketId, pBuffer->length); cleanUpAndExit(); } switch ( msg.msgBase.domainType ) { case RSSL_DMT_LOGIN: { RsslRDMLoginMsg loginMsg; char memoryChar[1024]; RsslBuffer memoryBuffer = { sizeof(memoryChar), memoryChar }; RsslErrorInfo errorInfo; RsslState *pState = NULL; if ((ret = rsslDecodeRDMLoginMsg(&dIter, &msg, &loginMsg, &memoryBuffer, &errorInfo)) != RSSL_RET_SUCCESS) { printf("rsslDecodeRDMLoginMsg() failed: %d(%s)\n", ret, errorInfo.rsslError.text); ret = RSSL_RET_FAILURE; break; } switch(loginMsg.rdmMsgBase.rdmMsgType) { case RDM_LG_MT_REFRESH: pState = &loginMsg.refresh.state; printf( "Received login refresh.\n"); if (loginMsg.refresh.flags & RDM_LG_RFF_HAS_APPLICATION_NAME) printf( " ApplicationName: %.*s\n", loginMsg.refresh.applicationName.length, loginMsg.refresh.applicationName.data); printf("\n"); break; case RDM_LG_MT_STATUS: printf("Received login status message.\n"); if (loginMsg.status.flags & RDM_LG_STF_HAS_STATE) pState = &loginMsg.status.state; break; default: printf("Received unhandled login message class: %d.\n", msg.msgBase.msgClass); break; } if (pState) { if (pState->streamState == RSSL_STREAM_OPEN) { ProviderSession *pProvSession = (ProviderSession*)pChannelInfo->pUserSpec; ret = publishDirectoryRefresh(pChannelHandler, pChannelInfo, -1); if (ret < RSSL_RET_SUCCESS) { printf("publishDirectoryRefresh() failed: %d.\n", ret); return ret; } if (niProvPerfConfig.itemPublishCount > 0) { RsslInt32 itemListUniqueIndex; RsslInt32 itemListCount; RsslInt32 itemListCountRemainder; /* If there are multiple connections, determine which items are * to be published on this connection. * If any items are common to all connections, they are taken from the first * items in the item list. The rest of the list is then divided to provide a unique * item list for each connection. */ /* Determine where items unique to this connection start. */ itemListUniqueIndex = niProvPerfConfig.commonItemCount; itemListUniqueIndex += ((niProvPerfConfig.itemPublishCount - niProvPerfConfig.commonItemCount) / providerThreadConfig.threadCount) * (pProviderThread->providerIndex); /* Account for remainder. */ itemListCount = niProvPerfConfig.itemPublishCount / providerThreadConfig.threadCount; itemListCountRemainder = niProvPerfConfig.itemPublishCount % providerThreadConfig.threadCount; if (pProviderThread->providerIndex < itemListCountRemainder) { /* This provider publishes an extra item */ itemListCount += 1; /* Shift index by one for each provider before this one, since they publish extra items too. */ itemListUniqueIndex += pProviderThread->providerIndex; } else /* Shift index by one for each provider that publishes an extra item. */ itemListUniqueIndex += itemListCountRemainder; if ((ret = providerSessionAddPublishingItems(pProviderThread, (ProviderSession*)pChannelInfo->pUserSpec, niProvPerfConfig.commonItemCount, itemListUniqueIndex, itemListCount - niProvPerfConfig.commonItemCount, (RsslUInt16)directoryConfig.serviceId)) != RSSL_RET_SUCCESS) { printf("providerSessionAddPublishingItems() failed\n"); return ret; } else { printf("Created publishing list.\n"); ret = RSSL_RET_SUCCESS; } /* send the first burst of refreshes */ if (rotatingQueueGetCount(&pProvSession->refreshItemList) != 0) ret = sendRefreshBurst(pProviderThread, pProvSession); else ret = RSSL_RET_SUCCESS; if (ret < RSSL_RET_SUCCESS) return ret; } if (ret > RSSL_RET_SUCCESS) { /* Need to flush */ providerThreadRequestChannelFlush(pProviderThread, pChannelInfo); } } else { printf("Login stream closed.\n"); ret = RSSL_RET_FAILURE; } } else ret = RSSL_RET_SUCCESS; break; } default: printf("Received message with unhandled domain: %d\n", msg.msgBase.domainType); break; } if (ret < RSSL_RET_SUCCESS) { signal_shutdown = RSSL_TRUE; return ret; } else { /* Typically these requests result in a response, so call for a flush to make sure it gets out.*/ providerThreadRequestChannelFlush(pProviderThread, pChannelInfo); return ret; } }