RsslReactorCallbackRet channelEventCallback(RsslReactor *pReactor, RsslReactorChannel *pReactorChannel, RsslReactorChannelEvent *pChannelEvent) { RsslBool clientSessionFound = RSSL_FALSE; RsslClientSessionInfo *pClientSessionInfo = (RsslClientSessionInfo*)pReactorChannel->userSpecPtr; switch(pChannelEvent->channelEventType) { case RSSL_RC_CET_CHANNEL_UP: { /* A channel that we have requested via rsslReactorAccept() has come up. Set our * file descriptor sets so we can be notified to start calling rsslReactorDispatch() for * this channel. */ #ifdef _WIN32 int rcvBfrSize = 65535; int sendBfrSize = 65535; RsslErrorInfo rsslErrorInfo; #endif printf("Connection up!\n"); pClientSessionInfo->clientChannel = pReactorChannel; printf("\nServer fd="SOCKET_PRINT_TYPE": New client on Channel fd="SOCKET_PRINT_TYPE"\n", pReactorChannel->pRsslServer->socketId, pReactorChannel->socketId); FD_SET(pReactorChannel->socketId, &readFds); FD_SET(pReactorChannel->socketId, &exceptFds); #ifdef _WIN32 /* WINDOWS: change size of send/receive buffer since it's small by default */ if (rsslReactorChannelIoctl(pReactorChannel, RSSL_SYSTEM_WRITE_BUFFERS, &sendBfrSize, &rsslErrorInfo) != RSSL_RET_SUCCESS) { printf("rsslReactorChannelIoctl(): failed <%s>\n", rsslErrorInfo.rsslError.text); } if (rsslReactorChannelIoctl(pReactorChannel, RSSL_SYSTEM_READ_BUFFERS, &rcvBfrSize, &rsslErrorInfo) != RSSL_RET_SUCCESS) { printf("rsslReactorChannelIoctl(): failed <%s>\n", rsslErrorInfo.rsslError.text); } #endif if (xmlTrace) { RsslErrorInfo rsslErrorInfo; RsslTraceOptions traceOptions; rsslClearTraceOptions(&traceOptions); traceOptions.traceMsgFileName = traceOutputFile; traceOptions.traceFlags |= RSSL_TRACE_TO_FILE_ENABLE | RSSL_TRACE_TO_STDOUT | RSSL_TRACE_TO_MULTIPLE_FILES | RSSL_TRACE_WRITE | RSSL_TRACE_READ; traceOptions.traceMsgMaxFileSize = 100000000; rsslReactorChannelIoctl(pReactorChannel, (RsslIoctlCodes)RSSL_TRACE, (void *)&traceOptions, &rsslErrorInfo); } return RSSL_RC_CRET_SUCCESS; } case RSSL_RC_CET_CHANNEL_READY: /* The channel has exchanged the messages necessary to setup the connection * and is now ready for general use. For an RDM Provider, this normally immediately * follows the CHANNEL_UP event. */ return RSSL_RC_CRET_SUCCESS; case RSSL_RC_CET_FD_CHANGE: /* The file descriptor representing the RsslReactorChannel has been changed. * Update our file descriptor sets. */ printf("Fd change: "SOCKET_PRINT_TYPE" to "SOCKET_PRINT_TYPE"\n", pReactorChannel->oldSocketId, pReactorChannel->socketId); FD_CLR(pReactorChannel->oldSocketId, &readFds); FD_CLR(pReactorChannel->oldSocketId, &exceptFds); FD_SET(pReactorChannel->socketId, &readFds); FD_SET(pReactorChannel->socketId, &exceptFds); return RSSL_RC_CRET_SUCCESS; case RSSL_RC_CET_WARNING: /* We have received a warning event for this channel. Print the information and continue. */ printf("Received warning for Channel fd="SOCKET_PRINT_TYPE".\n", pReactorChannel->socketId); printf(" Error text: %s\n", pChannelEvent->pError->rsslError.text); return RSSL_RC_CRET_SUCCESS; case RSSL_RC_CET_CHANNEL_DOWN: { /* The channel has failed and has gone down. Print the error, close the channel, and reconnect later. */ printf("Connection down!\n"); if (pChannelEvent->pError) printf(" Error text: %s\n", pChannelEvent->pError->rsslError.text); closeItemChnlStreams(pReactor, pReactorChannel); closeDictionaryChnlStreams(pReactorChannel); closeDirectoryStreamForChannel(pReactorChannel); closeLoginStreamForChannel(pReactorChannel); if(pClientSessionInfo->clientChannel == NULL) { pClientSessionInfo->clientChannel = pReactorChannel; } /* It is important to make sure that no more interface calls are made using the channel after * calling rsslReactorCloseChannel(). Because this application is single-threaded, it is safe * to call it inside callback functions. */ removeClientSessionForChannel(pReactor, pReactorChannel); return RSSL_RC_CRET_SUCCESS; } default: printf("Unknown channel event!\n"); cleanUpAndExit(); } return RSSL_RC_CRET_SUCCESS; }
RsslReactorCallbackRet channelEventCallback(RsslReactor *pReactor, RsslReactorChannel *pReactorChannel, RsslReactorChannelEvent *pChannelEvent) { ProviderSession *pProvSession = (ProviderSession *)pReactorChannel->userSpecPtr; ProviderThread *pProviderThread = pProvSession->pProviderThread; RsslErrorInfo rsslErrorInfo; RsslReactorChannelInfo reactorChannelInfo; RsslUInt32 count; RsslRet ret; switch(pChannelEvent->channelEventType) { case RSSL_RC_CET_CHANNEL_UP: { /* A channel that we have requested via rsslReactorAccept() has come up. Set our * file descriptor sets so we can be notified to start calling rsslReactorDispatch() for * this channel. */ FD_SET(pReactorChannel->socketId, &pProviderThread->readfds); FD_SET(pReactorChannel->socketId, &pProviderThread->exceptfds); #ifdef ENABLE_XML_TRACE RsslTraceOptions traceOptions; rsslClearTraceOptions(&traceOptions); traceOptions.traceMsgFileName = "upacProvPerf"; traceOptions.traceMsgMaxFileSize = 1000000000; traceOptions.traceFlags |= RSSL_TRACE_TO_FILE_ENABLE | RSSL_TRACE_WRITE | RSSL_TRACE_READ; rsslIoctl(pChannelInfo->pChannel, (RsslIoctlCodes)RSSL_TRACE, (void *)&traceOptions, &error); #endif if (provPerfConfig.highWaterMark > 0) { if (rsslReactorChannelIoctl(pReactorChannel, RSSL_HIGH_WATER_MARK, &provPerfConfig.highWaterMark, &rsslErrorInfo) != RSSL_RET_SUCCESS) { printf("rsslReactorChannelIoctl() of RSSL_HIGH_WATER_MARK failed <%s>\n", rsslErrorInfo.rsslError.text); exit(-1); } } if ((ret = rsslReactorGetChannelInfo(pReactorChannel, &reactorChannelInfo, &rsslErrorInfo)) != RSSL_RET_SUCCESS) { printf("rsslReactorGetChannelInfo() failed: %d\n", ret); return RSSL_RC_CRET_SUCCESS; } 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: ", pReactorChannel->socketId, reactorChannelInfo.rsslChannelInfo.maxFragmentSize, reactorChannelInfo.rsslChannelInfo.maxOutputBuffers, reactorChannelInfo.rsslChannelInfo.guaranteedOutputBuffers, reactorChannelInfo.rsslChannelInfo.numInputBuffers, reactorChannelInfo.rsslChannelInfo.pingTimeout, reactorChannelInfo.rsslChannelInfo.clientToServerPings == RSSL_TRUE ? "true" : "false", reactorChannelInfo.rsslChannelInfo.serverToClientPings == RSSL_TRUE ? "true" : "false", reactorChannelInfo.rsslChannelInfo.sysSendBufSize, reactorChannelInfo.rsslChannelInfo.sysRecvBufSize, reactorChannelInfo.rsslChannelInfo.compressionType == RSSL_COMP_ZLIB ? "zlib" : "none", reactorChannelInfo.rsslChannelInfo.compressionThreshold ); if (reactorChannelInfo.rsslChannelInfo.componentInfoCount == 0) printf("(No component info)"); else for(count = 0; count < reactorChannelInfo.rsslChannelInfo.componentInfoCount; ++count) { printf("%.*s", reactorChannelInfo.rsslChannelInfo.componentInfo[count]->componentVersion.length, reactorChannelInfo.rsslChannelInfo.componentInfo[count]->componentVersion.data); if (count < reactorChannelInfo.rsslChannelInfo.componentInfoCount - 1) printf(", "); } printf ("\n\n"); /* Check that we can successfully pack, if packing messages. */ if (providerThreadConfig.totalBuffersPerPack > 1 && providerThreadConfig.packingBufferLength > reactorChannelInfo.rsslChannelInfo.maxFragmentSize) { printf("Error(Channel %d): MaxFragmentSize %u is too small for packing buffer size %u\n", pReactorChannel->socketId, reactorChannelInfo.rsslChannelInfo.maxFragmentSize, providerThreadConfig.packingBufferLength); exit(-1); } pProvSession->pChannelInfo->pChannel = pReactorChannel->pRsslChannel; pProvSession->pChannelInfo->pReactorChannel = pReactorChannel; pProvSession->pChannelInfo->pReactor = pReactor; rsslQueueAddLinkToBack(&pProviderThread->channelHandler.activeChannelList, &pProvSession->pChannelInfo->queueLink); pProvSession->timeActivated = getTimeNano(); return RSSL_RC_CRET_SUCCESS; } case RSSL_RC_CET_CHANNEL_READY: { if (ret = (printEstimatedMsgSizes(pProviderThread, pProvSession)) != RSSL_RET_SUCCESS) { printf("printEstimatedMsgSizes() failed: %d\n", ret); return RSSL_RC_CRET_SUCCESS; } return RSSL_RC_CRET_SUCCESS; } case RSSL_RC_CET_FD_CHANGE: { /* The file descriptor representing the RsslReactorChannel has been changed. * Update our file descriptor sets. */ printf("Fd change: %d to %d\n", pReactorChannel->oldSocketId, pReactorChannel->socketId); FD_CLR(pReactorChannel->oldSocketId, &pProviderThread->readfds); FD_CLR(pReactorChannel->oldSocketId, &pProviderThread->exceptfds); FD_SET(pReactorChannel->socketId, &pProviderThread->readfds); FD_SET(pReactorChannel->socketId, &pProviderThread->exceptfds); return RSSL_RC_CRET_SUCCESS; } case RSSL_RC_CET_WARNING: { /* We have received a warning event for this channel. Print the information and continue. */ printf("Received warning for Channel fd=%d.\n", pReactorChannel->socketId); printf(" Error text: %s\n", pChannelEvent->pError->rsslError.text); return RSSL_RC_CRET_SUCCESS; } case RSSL_RC_CET_CHANNEL_DOWN: { pProviderThread->stats.inactiveTime = getTimeNano(); printf("Channel Closed.\n"); FD_CLR(pReactorChannel->socketId, &pProviderThread->readfds); FD_CLR(pReactorChannel->socketId, &pProviderThread->exceptfds); --pProviderThread->clientSessionsCount; if (pProvSession->pChannelInfo->pReactorChannel && rsslQueueGetElementCount(&pProviderThread->channelHandler.activeChannelList) > 0) { rsslQueueRemoveLink(&pProviderThread->channelHandler.activeChannelList, &pProvSession->pChannelInfo->queueLink); } if (pProvSession) { free(pProvSession->pChannelInfo); providerSessionDestroy(pProviderThread, pProvSession); } if (rsslReactorCloseChannel(pReactor, pReactorChannel, &rsslErrorInfo) != RSSL_RET_SUCCESS) { printf("rsslReactorCloseChannel() failed: %s\n", rsslErrorInfo.rsslError.text); cleanUpAndExit(); } return RSSL_RC_CRET_SUCCESS; } default: printf("Unknown channel event!\n"); cleanUpAndExit(); } return RSSL_RC_CRET_SUCCESS; }
RsslReactorCallbackRet channelEventCallback(RsslReactor *pReactor, RsslReactorChannel *pReactorChannel, RsslReactorChannelEvent *pConnEvent) { NIChannelCommand *chanCommand; #ifdef _WIN32 int rcvBfrSize = 65535; int sendBfrSize = 65535; RsslErrorInfo rsslErrorInfo; #endif chanCommand = (NIChannelCommand*)pReactorChannel->userSpecPtr; switch(pConnEvent->channelEventType) { case RSSL_RC_CET_CHANNEL_UP: printf("Connection up!\n"); FD_SET(pReactorChannel->socketId, &readFds); FD_SET(pReactorChannel->socketId, &exceptFds); chanCommand->reactorChannel = pReactorChannel; #ifdef _WIN32 /* WINDOWS: change size of send/receive buffer since it's small by default */ if (rsslReactorChannelIoctl(pReactorChannel, RSSL_SYSTEM_WRITE_BUFFERS, &sendBfrSize, &rsslErrorInfo) != RSSL_RET_SUCCESS) { printf("rsslReactorChannelIoctl(): failed <%s>\n", rsslErrorInfo.rsslError.text); } if (rsslReactorChannelIoctl(pReactorChannel, RSSL_SYSTEM_READ_BUFFERS, &rcvBfrSize, &rsslErrorInfo) != RSSL_RET_SUCCESS) { printf("rsslReactorChannelIoctl(): failed <%s>\n", rsslErrorInfo.rsslError.text); } #endif if (xmlTrace) { RsslErrorInfo rsslErrorInfo; RsslTraceOptions traceOptions; rsslClearTraceOptions(&traceOptions); traceOptions.traceMsgFileName = traceOutputFile; traceOptions.traceFlags |= RSSL_TRACE_TO_FILE_ENABLE | RSSL_TRACE_TO_STDOUT | RSSL_TRACE_TO_MULTIPLE_FILES | RSSL_TRACE_WRITE | RSSL_TRACE_READ; traceOptions.traceMsgMaxFileSize = 100000000; rsslReactorChannelIoctl(pReactorChannel, (RsslIoctlCodes)RSSL_TRACE, (void *)&traceOptions, &rsslErrorInfo); } break; case RSSL_RC_CET_WARNING: /* We have received a warning event for this channel. Print the information and continue. */ printf("Received warning for Channel fd="SOCKET_PRINT_TYPE".\n", pReactorChannel->socketId); printf(" Error text: %s\n", pConnEvent->pError->rsslError.text); return RSSL_RC_CRET_SUCCESS; case RSSL_RC_CET_FD_CHANGE: printf("Fd change: "SOCKET_PRINT_TYPE" to "SOCKET_PRINT_TYPE"\n", pReactorChannel->oldSocketId, pReactorChannel->socketId); FD_CLR(pReactorChannel->oldSocketId, &readFds); FD_CLR(pReactorChannel->oldSocketId, &exceptFds); FD_SET(pReactorChannel->socketId, &readFds); FD_SET(pReactorChannel->socketId, &exceptFds); break; case RSSL_RC_CET_CHANNEL_DOWN: printf("Connection down: Channel fd="SOCKET_PRINT_TYPE" Requesting reconnect.\n", pReactorChannel->socketId); chanCommand = (NIChannelCommand*)pReactorChannel->userSpecPtr; recoverConnection(pReactor, pReactorChannel, chanCommand); break; case RSSL_RC_CET_CHANNEL_READY: printf("Connection is ready, starting publishing\n"); chanCommand->startWrite = RSSL_TRUE; break; default: printf("Unknown connection event!\n"); return RSSL_RC_CRET_SUCCESS; } if (pConnEvent->pError) printf(" Error text: %s\n", pConnEvent->pError->rsslError.text); return RSSL_RC_CRET_SUCCESS; }
RsslBuffer* tunnelManagerGetChannelBuffer(TunnelManagerImpl *pManagerImpl, RsslEncodeIterator *pIter, RsslUInt32 length, RsslBool mustSendMsg, RsslErrorInfo *pErrorInfo) { RsslBuffer *pBuffer; RsslReactorChannel *pReactorChannel = pManagerImpl->base._pReactorChannel; RsslRet ret; assert(pReactorChannel); if ((pBuffer = rsslReactorGetBuffer(pReactorChannel, length, RSSL_FALSE, pErrorInfo)) == NULL) { RsslReactorChannelInfo channelInfo; if (!mustSendMsg) return NULL; if (pErrorInfo->rsslError.rsslErrorId != RSSL_RET_BUFFER_NO_BUFFERS) return NULL; if ((ret = rsslReactorGetChannelInfo(pReactorChannel, &channelInfo, pErrorInfo) != RSSL_RET_SUCCESS)) return NULL; /* Grow the buffer pool by one and attempt to get the buffer again. */ /* Try the shared pool first. */ channelInfo.rsslChannelInfo.maxOutputBuffers += 1; if ((ret = rsslReactorChannelIoctl(pReactorChannel, RSSL_MAX_NUM_BUFFERS, &channelInfo.rsslChannelInfo.maxOutputBuffers, pErrorInfo)) != RSSL_RET_SUCCESS) { /* If that doesn't work, try the guaranteed pool. */ channelInfo.rsslChannelInfo.guaranteedOutputBuffers += 1; if ((ret = rsslReactorChannelIoctl(pReactorChannel, RSSL_NUM_GUARANTEED_BUFFERS, &channelInfo.rsslChannelInfo.guaranteedOutputBuffers, pErrorInfo)) != RSSL_RET_SUCCESS) return NULL; } if ((pBuffer = rsslReactorGetBuffer(pReactorChannel, length, RSSL_FALSE, pErrorInfo)) == NULL) return NULL; } if (pIter != NULL) { rsslClearEncodeIterator(pIter); rsslSetEncodeIteratorRWFVersion(pIter, pReactorChannel->majorVersion, pReactorChannel->minorVersion); if ((ret = rsslSetEncodeIteratorBuffer(pIter, pBuffer)) != RSSL_RET_SUCCESS) { RsslErrorInfo errorInfo; rsslReactorReleaseBuffer(pReactorChannel, pBuffer, &errorInfo); rsslSetErrorInfo(pErrorInfo, RSSL_EIC_FAILURE, RSSL_RET_FAILURE, __FILE__, __LINE__, "Failed to set encode iterator on buffer."); return NULL; } } return pBuffer; }
/* * Processes events about the state of an RsslReactorChannel. */ RsslReactorCallbackRet channelEventCallback(RsslReactor *pReactor, RsslReactorChannel *pReactorChannel, RsslReactorChannelEvent *pConnEvent) { ChannelStorage *pCommand = (ChannelStorage*)pReactorChannel->userSpecPtr; switch(pConnEvent->channelEventType) { case RSSL_RC_CET_CHANNEL_UP: { /* A channel that we have requested via rsslReactorConnect() has come up. Set our * file descriptor sets so we can be notified to start calling rsslReactorDispatch() for * this channel. This will drive the process of setting up the connection * by exchanging the Login, Directory, and (if not already loaded)Dictionary messages. * The application will receive the response messages in the appropriate callback * function we specified. */ #ifdef _WIN32 int rcvBfrSize = 65535; int sendBfrSize = 65535; RsslErrorInfo rsslErrorInfo; #endif printf("Connection up! Channel fd=%d\n\n", pReactorChannel->socketId); /* Set file descriptor. */ FD_SET(pReactorChannel->socketId, &readFds); FD_SET(pReactorChannel->socketId, &exceptFds); /* Save the channel on our info structure. */ pCommand->reactorChannel = pReactorChannel; #ifdef _WIN32 /* WINDOWS: change size of send/receive buffer since it's small by default */ if (rsslReactorChannelIoctl(pReactorChannel, RSSL_SYSTEM_WRITE_BUFFERS, &sendBfrSize, &rsslErrorInfo) != RSSL_RET_SUCCESS) { printf("rsslReactorChannelIoctl(): failed <%s>\n", rsslErrorInfo.rsslError.text); } if (rsslReactorChannelIoctl(pReactorChannel, RSSL_SYSTEM_READ_BUFFERS, &rcvBfrSize, &rsslErrorInfo) != RSSL_RET_SUCCESS) { printf("rsslReactorChannelIoctl(): failed <%s>\n", rsslErrorInfo.rsslError.text); } #endif if (xmlTrace) { RsslTraceOptions traceOptions; RsslErrorInfo rsslErrorInfo; rsslClearTraceOptions(&traceOptions); traceOptions.traceMsgFileName = traceOutputFile; traceOptions.traceFlags |= RSSL_TRACE_TO_FILE_ENABLE | RSSL_TRACE_TO_STDOUT | RSSL_TRACE_TO_MULTIPLE_FILES | RSSL_TRACE_WRITE | RSSL_TRACE_READ; traceOptions.traceMsgMaxFileSize = 100000000; rsslReactorChannelIoctl(pReactorChannel, (RsslIoctlCodes)RSSL_TRACE, (void *)&traceOptions, &rsslErrorInfo); } return RSSL_RC_CRET_SUCCESS; } case RSSL_RC_CET_CHANNEL_READY: { pCommand->reactorChannelReady = RSSL_TRUE; return RSSL_RC_CRET_SUCCESS; } case RSSL_RC_CET_FD_CHANGE: { /* The file descriptor representing the RsslReactorChannel has been changed. * Update our file descriptor sets. */ printf("Fd change: %d to %d\n", pReactorChannel->oldSocketId, pReactorChannel->socketId); FD_CLR(pReactorChannel->oldSocketId, &readFds); FD_CLR(pReactorChannel->oldSocketId, &exceptFds); FD_SET(pReactorChannel->socketId, &readFds); FD_SET(pReactorChannel->socketId, &exceptFds); return RSSL_RC_CRET_SUCCESS; } case RSSL_RC_CET_CHANNEL_DOWN: { /* The channel has failed and has gone down. Print the error, close the channel, and reconnect later. */ printf("Connection down: Channel fd=%d.\n", pReactorChannel->socketId); if (pConnEvent->pError) printf(" Error text: %s\n\n", pConnEvent->pError->rsslError.text); /* It is important to make sure that no more interface calls are made using the channel after * calling rsslReactorCloseChannel(). Because this application is single-threaded, it is safe * to call it inside callback functions. */ closeConnection(pReactor, pReactorChannel, pCommand); return RSSL_RC_CRET_SUCCESS; } case RSSL_RC_CET_CHANNEL_DOWN_RECONNECTING: { printf("Connection down, reconnecting. Channel fd=%d\n", pReactorChannel->socketId); if (pReactorChannel->socketId != REACTOR_INVALID_SOCKET) { FD_CLR(pReactorChannel->socketId, &readFds); FD_CLR(pReactorChannel->socketId, &exceptFds); } clearChannelStorage(pCommand); return RSSL_RC_CRET_SUCCESS; } case RSSL_RC_CET_WARNING: { /* We have received a warning event for this channel. Print the information and continue. */ printf("Received warning for Channel fd=%d.\n", pReactorChannel->socketId); printf(" Error text: %s\n\n", pConnEvent->pError->rsslError.text); return RSSL_RC_CRET_SUCCESS; } default: { printf("Unknown connection event!\n"); cleanUpAndExit(-1); } } return RSSL_RC_CRET_SUCCESS; }