Example #1
0
//don't call this
//--------------------------
void ofxTCPServer::threadedFunction(){

	ofLogVerbose("ofxTCPServer") << "listening thread started";
	while( isThreadRunning() ){
		
		int acceptId;
		for(acceptId = 0; acceptId <= idCount; acceptId++){
			if(!isClientConnected(acceptId)) break;
		}
		
		if(acceptId == TCP_MAX_CLIENTS){
			ofLogWarning("ofxTCPServer") << "no longer accepting connections, maximum number of clients reached: " << TCP_MAX_CLIENTS;
			break;
		}

		if( !TCPServer.Listen(TCP_MAX_CLIENTS) ){
			if(isThreadRunning()) ofLogError("ofxTCPServer") << "listening failed";
		}

        {
			std::unique_lock<std::mutex> lck( mConnectionsLock );
            serverReady.notify_one();
        }
		
		//	we need to lock here, but can't as it blocks...
		//	so use a temporary to not block the lock 
		std::shared_ptr<ofxTCPClient> client(new ofxTCPClient);
		if( !TCPServer.Accept( client->TCPClient ) ){
			if(isThreadRunning()) ofLogError("ofxTCPServer") << "couldn't accept client " << acceptId;
		}else{
			std::unique_lock<std::mutex> lck( mConnectionsLock );
			//	take owenership of socket from NewClient
			TCPConnections[acceptId] = client;
            TCPConnections[acceptId]->setupConnectionIdx(acceptId, bClientBlocking);
			TCPConnections[acceptId]->setMessageDelimiter(messageDelimiter);
			ofLogVerbose("ofxTCPServer") << "client " << acceptId << " connected on port " << TCPConnections[acceptId]->getPort();
			if(acceptId == idCount) idCount++;
			serverReady.notify_all();
		}
	}
	idCount = 0;
	std::unique_lock<std::mutex> lck( mConnectionsLock );
	TCPConnections.clear();
	connected = false;
	ofLogVerbose("ofxTCPServer") << "listening thread stopped";
}
//------------------------------------------------------------------------------
void ofxMatrixNetworkServer::readResponse()
{
 	//for each connected client lets get the data being sent and lets print it to the screen
	for(unsigned int i = 0; i < (unsigned int)getLastID(); i++){
        
		if( !isClientConnected(i) )continue;

        // TODO read latency data here.
        char buf[MAXDATASIZE]; 
        int numBytes = receiveRawBytes(i, buf, MAXDATASIZE-1);
        if (numBytes == -1)
        {
            // printf("recv error\n");
            // skip it, there's nothing there
        }
        else
        {
            buf[numBytes] = '\0'; // end it
            
            m_latencyPacket.id                      = ((t_jit_net_packet_latency *)buf)->id; // cast it to get the id
            m_latencyPacket.client_time_original    = ((t_jit_net_packet_latency *)buf)->client_time_original;
            m_latencyPacket.server_time_before_data = ((t_jit_net_packet_latency *)buf)->server_time_before_data;
            m_latencyPacket.server_time_after_data  = ((t_jit_net_packet_latency *)buf)->server_time_after_data;
            
    //printf("id: %d\n", (m_latencyPacket.id));
    //printf("client time original %f\n",m_latencyPacket.client_time_original);
    //printf("before Data %fl\n",m_latencyPacket.server_time_before_data);
    //printf("after Data %f\n",m_latencyPacket.server_time_after_data);
    //printf("diff=%f\n\n",m_latencyPacket.server_time_after_data - m_latencyPacket.server_time_before_data);
            
            // cout << buf << endl;
            
            // if(lastSent >= m_latencyPacket.client_time_original) {
            //  printf("GTOE => last sent=%f and client_time_original=%f\n",lastSent,m_latencyPacket.client_time_original);	
            // } else {
            //  printf("NNNWWW => last sent=%f and client_time_original=%f\n",lastSent,m_latencyPacket.client_time_original);	
            // }
        }
    }
}
//--------------------------------------------------------------
void ofxMatrixNetworkServer::update() {
    //for each client lets send them a message letting them know what port they are connected on
	for(int i = 0; i < getLastID(); i++){
		if(isClientConnected(i)){
            //if we don't have a string allocated yet: lets create one
            //if(i >= storeText.size() ){
            //    storeText.push_back( string() );
            //}
            
            //if we don't have a string allocated yet: lets create one
            if(i >= tx_valid.size() ){
                tx_valid.push_back(0);
            }
            
            //we only want to update the text we have recieved there is data
            string str = receive(i);
            
            if(str == "handshake"){
                ofLog(OF_LOG_NOTICE, "handshake with client " + ofToString(i));
                sendHandshake(i);
                tx_valid[i] = 1;
            }else if(str.find_first_of("nextframe") != -1){
                //ofLog(OF_LOG_NOTICE, "nextframe for client " + ofToString(i) + " - " + str);
                tx_valid[i] = 2;
            }else if(str == "disconnect"){
                ofLog(OF_LOG_NOTICE, "disconnect client " + ofToString(i));
                sendDisconnect(i);
                disconnectClient(i);
                tx_valid[i] = 0;
            }
            
            //if(str.length() > 0){
            //    storeText[i] = str;
            //}
        }else{
            tx_valid[i] = 0;
        }
	}
}
//don't call this
//--------------------------
void WebSocketServer::threadedFunction(){
	
	while( isThreadRunning() ){
		
		int acceptId;
		for(acceptId = 0; acceptId <= idCount; acceptId++){
			if(!isClientConnected(acceptId)) break;
		}
		
		if(acceptId == WEBSOCKET_MAX_CLIENTS){
			if(verbose)printf("WebSocketServer: reached max connected clients! \nWebSocketServer: no more connections accepted\n");
			break;
		}
		
		if( !TCPManager.Listen(WEBSOCKET_MAX_CLIENTS) ){
			if(verbose)printf("WebSocketServer: Listen() failed\n");
		}
		
		// this check makes a new client at acceptId, in other words, 
		// the next available slot. Seems weird to me but what do I know?
		// maybe Accept is a blocking function? 
		
		if( !TCPManager.Accept(webSocketClients[acceptId].TCPClient) ){
			if(verbose)printf("WebSocketServer: Accept() failed\n");
		}else{
			
			webSocketClients[acceptId].serverPortNum = port; // this is for the handshake
			webSocketClients[acceptId].setup(acceptId, bClientBlocking);
			
			if(verbose)printf("WebSocketServer: client %i connected on port %i\n", acceptId, webSocketClients[acceptId].getPort());
			
			if(acceptId == idCount) idCount++;
		}
	}
	if(verbose)printf("WebSocketServer: listen thread ended\n");
}
//------------------------------------------------------------------------------
void ofxMatrixNetworkServer::sendText(const string& txt) {
	//for each connected client lets get the data being sent and lets print it to the screen
	for(unsigned int i = 0; i < (unsigned int)getLastID(); i++){
        
		if( !isClientConnected(i) )continue;
        m_messageHeader.id = SWAP32(JIT_MESSAGE_PACKET_ID);
        m_messageHeader.size = SWAP32(sizeof(long) + // size
                                      sizeof(long) + // ac
                                      sizeof(char) + // type
                                      sizeof(char)*txt.length() + // number
                                      sizeof(char)); // null terminator
        
        sendRawBytes(i, (char *)&m_messageHeader.id, sizeof(long));
        sendRawBytes(i, (char *)&m_messageHeader.size, sizeof(long));
        
        // the packet
        long messageSizeBytes = m_messageHeader.size; //	32-bit integer that contains the size of the serialized message in bytes. 
        long ac = SWAP32(0);      //    Following that another 32-bit integer gives the argument count for the atoms. 
        /// Following that comes the message atoms themselves, starting with the leading symbol if it exists. 
        //  Each atom is represented in memory first with a char that indicates what type of atom it is:
        //		's' for symbol, 'l' for long, and 'f' for float. 
        //		For long and float atoms, the next 4 bytes contain the value of the atom; 
        //		for symbol atoms a null terminated character string follows. 
        
        
        char atomType = 's'; //'s' for symbol, 'l' for long, and 'f' for float. 
        const char *cp = txt.c_str(); // seriously
        char nullTerm = '\0';
        sendRawBytes(i, (char *)&messageSizeBytes, sizeof(long));
        sendRawBytes(i, (char *)&ac, sizeof(long));
        sendRawBytes(i, (char *)&atomType, sizeof(char));
        sendRawBytes(i, (char *)cp, txt.length()*sizeof(char));
        sendRawBytes(i, (char *)&nullTerm, sizeof(char));
        //readResponse();
    }
}
//------------------------------------------------------------------------------
void ofxMatrixNetworkServer::sendFrame(const ofFloatPixelsRef pixels)
{
	//for each connected client lets get the data being sent and lets print it to the screen
	for(unsigned int i = 0; i < (unsigned int)getLastID(); i++){
        
		if(isClientConnected(i) && tx_valid[i] == 2){
            tx_valid[i] = 1;
            
            int planecount = pixels.getNumChannels();
            int dimcount = 2; // only sending 2d matrices from of
            int dim[dimcount];
            dim[0]       = pixels.getWidth();
            dim[1]       = pixels.getHeight();
            int typeSize = pixels.getBytesPerChannel();
            int type     = JIT_MATRIX_TYPE_FLOAT32;
            
            makeMatrixHeader(planecount, typeSize, type, dim, dimcount);
            
            char *matrix = (char*)pixels.getPixels();
            
            
            //////SEND ONE MATRIX
            sendRawBytes(i, (char *)(&m_chunkHeader), sizeof(t_jit_net_packet_header));
            sendRawBytes(i, (char *)(&m_matrixHeader), sizeof(t_jit_net_packet_matrix));
            
            //DELETE THIS LINE
            //int packSize = SWAP32(m_matrixHeader.dimstride[dimcount-1])*SWAP32(m_matrixHeader.dim[dimcount-1]);
            
            //ofLog(OF_LOG_NOTICE, "send frame to client: " + ofToString(i));
            int vector = dim[0] * typeSize * planecount;
            for(int j = 0; j < dim[1]; j++){
                sendRawBytes(i, matrix + j * vector, vector);
            }
        }
    }
}