Cinder-Asio's TcpCleint strange behavior

Hi all,

I posted this on the issues page of the Cinder-Asio github repo but since that repo looks inactive, I thought to ask it here as well and also to help others not to face the same issue in the future for whatever it’s worth. So here it goes:

I just wanted to point out a very strange behavior I faced when making a simple messaging system with a libcinder app as a TCP Client and a node.js TCP server on LAN:

Modifying the TcpClient sample, I removed the mSession->close() line from the end of the onRead method because unlike the sample I wanted to keep my connection alive with the server for many hours. I replaced that line with a “mSession->read()” because I wanted the client to keep listening of course and I needed it there because I didn’t necessarily write back to server after I read a buffer so I couldn’t just keep the mSession->read() at the end of the onWrite() method. I still kept that though so that the client could keep listening after every time it wrote a message to the sever. But as my code evolved I noticed that sometimes the client read an empty buffer in onRead() whereas it should have read a message. I played around with the code and realized that removing mSession->read() from onWrite mitigated the bug! Should that be the case? Why would having 2 read() calls on the session conflict each other? Is that an expected result or was I doing something wrong? On the whole, why do we need to say mSession->read() every time and can’t we have a client that is constantly listening/reading?

Here’s the final relevant bits of code (the commented line actually messes things up)

void BoomerangRecorderApp::onConnect( TcpSessionRef session )
	warningToConsole( "Connected" );
	mIsClientConnected = true;
	mSession = session;
	mSession->connectCloseEventHandler( [&]() {
		warningToConsole( "Disconnected" );
		mIsClientConnected = false;
	} );
	mSession->connectErrorEventHandler( &BoomerangRecorderApp::onError, this );
	mSession->connectReadCompleteEventHandler( [&]() {
		warningToConsole( "Read complete" );
	} );
	mSession->connectReadEventHandler( &BoomerangRecorderApp::onRead, this );
	mSession->connectWriteEventHandler( &BoomerangRecorderApp::onWrite, this );
	writeMessage( "FROM_CINDER_hello_" + toString( mPlayerIndex ) + "\n" );

void BoomerangRecorderApp::onRead( ci::BufferRef buffer )

	string response = TcpSession::bufferToString( buffer );
	mResponseChunk += response;
	warningToConsole( "On Read buffer - response chunk is : " + mResponseChunk + "---" );
	while( mResponseChunk.find('\n') != string::npos) {
		processMessage( mResponseChunk );
		if( mResponseChunk.length() > mResponseChunk.find( '\n' ) + 1 ) {
			warningToConsole( "More messages found!!" );
			mResponseChunk = mResponseChunk.substr( mResponseChunk.find( '\n' ) + 1 );
		else {
			mResponseChunk = "";

void BoomerangRecorderApp::onWrite( size_t bytesTransferred )

I also had to add a mSession->read() to onConnect as you can see to initiate the listening but I don’t think that has anything to do with problem. It more looks like a conflict between the two read() calls on onRead()and onWrite()