Example #1
0
int main(int argc, char *argv[]) {
    
    std::cout << "Performance test for the RPC314 plugin." << std::endl;
    
    bool isServer = false;
    bool testAll = false;
    bool testSignal = false;
    bool testCallC = false;
    bool testCallCpp = false;
    bool useBoost = false;
    unsigned int clientCount = 1;
    unsigned int callCount = 1;
    
    int opt;
    while (1) {
        static struct option long_options[] = {
            {"use-boost",   no_argument, 0, 'b'},
            {"test",    required_argument, 0, 't'},
            {"client-count",    required_argument, 0, 'c'},
            {"call-count",    required_argument, 0, 'r'},
            {0, 0, 0, 0}
        };
        
        // getopt_long stores the option index here.
        int option_index = 0;
        
        opt = getopt_long(argc, argv, "bc:t:", long_options, &option_index);
        
        // Detect the end of the options.
        if (opt == -1) {
            break;
        }
    
        switch (opt) {
            case 0:
                break;
            case 'b':
                useBoost = true;
                break;
            case 'c':
                clientCount = atoi(optarg);
                break;
            case 'r':
                callCount = atoi(optarg);
                break;
            case 't': {
                if (optarg == "all") {
                    testAll = true;
                }
                else if (optarg == "signal") {
                    testSignal = true;
                }
                else if (optarg == "c") {
                    testCallC = true;
                }
                else if (optarg == "cpp") {
                    testCallCpp = true;
                }
                else {
                    testAll = true;
                }
            } break;
            case '?':
                return 1;
            default:
                testAll = true;
                break;
        }
    }

    TestValues testValues;
    testValues.allReady = false;
    
    uint64_t programStartTime = RakNet::GetTimeUS();
    
    std::unique_ptr<std::recursive_mutex> mutex_(new std::recursive_mutex());

    unsigned int peerCount = clientCount + 1;
    std::vector<RakNet::RakPeerInterface *> rakPeers;
    //rakPeers.assign(peerCount, RakNet::RakPeerInterface::GetInstance());
    
    std::vector<RakNet::RPC3 *> rpcPlugins;
    //rpcPlugins.assign(peerCount, new RakNet::RPC3());
    
    std::vector<RakNet::NetworkIDManager> networkIdManagers;
    networkIdManagers.assign(peerCount, RakNet::NetworkIDManager());
    
    std::vector<BaseClassA> a;
    a.assign(peerCount, BaseClassA());
    
    std::vector<BaseClassB> b;
    b.assign(peerCount, BaseClassB());
    
    std::vector<ClassC> c;
    c.assign(peerCount, ClassC());
    
    std::vector<ClassD> d;
    d.assign(peerCount, ClassD());
    
    for (std::size_t i = 0; i < peerCount; i++) {
        rakPeers.push_back(RakNet::RakPeerInterface::GetInstance());
        rpcPlugins.push_back(new RakNet::RPC3());
        
        if (i == 0) {
            RakNet::SocketDescriptor socketDescriptorServer(60000, 0);
            // Only IPV4 supports broadcast on 255.255.255.255
            socketDescriptorServer.socketFamily = AF_INET;
            
            rakPeers[i]->Startup(clientCount, &socketDescriptorServer, 1);
            rakPeers[i]->SetMaximumIncomingConnections(clientCount);
            
            std::cout << "Server started." << std::endl;
        }
        else {
            RakNet::SocketDescriptor socketDescriptorClient(60000 + i, 0);
            // Only IPV4 supports broadcast on 255.255.255.255
            socketDescriptorClient.socketFamily = AF_INET;
            
            rakPeers[i]->Startup(1, &socketDescriptorClient, 1);

            // Send out a LAN broadcast to find the server on the same computer.
            rakPeers[i]->Ping("255.255.255.255", 60000, true, 0);

            std::cout << "Client #" << i << " started." << std::endl;
        }
        
        rakPeers[i]->AttachPlugin(rpcPlugins[i]);
        rpcPlugins[i]->SetNetworkIDManager(&networkIdManagers[i]);
        
        c[i].SetNetworkIDManager(&networkIdManagers[i]);
        d[i].SetNetworkIDManager(&networkIdManagers[i]);
        c[i].SetNetworkID(0);
        d[i].SetNetworkID(1);
    
        // Register a regular C function.
        RPC3_REGISTER_FUNCTION(rpcPlugins[i], CFuncTest);
        
        // Register C++ class member functions.
        RPC3_REGISTER_FUNCTION(rpcPlugins[i], &ClassC::ClassMemberFuncTest);
        
        // All equivalent local and remote slots are called when a signal is sent.
        rpcPlugins[i]->RegisterSlot(
                "TestSlotTest", &ClassC::TestSlotTest, c[i].GetNetworkID(), 0);
        rpcPlugins[i]->RegisterSlot(
                "TestSlotTest", &ClassD::TestSlotTest, d[i].GetNetworkID(), 0);
    }
    
    std::cout << "Clients will automatically connect to running server." << std::endl;
    std::cout << "Running " << callCount << " rounds." << std::endl;

    
    RakNet::Packet *packet;
    std::thread serverT;
    bool allready = true;
    while (!testValues.allReady) {
        for (std::size_t i = 0; i < peerCount; i++) {
            for (packet=rakPeers[i]->Receive(); packet;
                    rakPeers[i]->DeallocatePacket(packet), packet=rakPeers[i]->Receive()) {
                switch (packet->data[0]) {
                    case ID_DISCONNECTION_NOTIFICATION:
                        std::cout << "ID_DISCONNECTION_NOTIFICATION peer index:"
                                  << i << std::endl;
                        break;
                    case ID_ALREADY_CONNECTED:
                        std::cout << "ID_ALREADY_CONNECTED peer index:" << i
                                  << std::endl;
                        break;
                    case ID_CONNECTION_ATTEMPT_FAILED:
                        std::cout << "Connection attempt failed peer index:"
                                  << i << std::endl;
                        break;
                    case ID_NO_FREE_INCOMING_CONNECTIONS:
                        std::cout << "ID_NO_FREE_INCOMING_CONNECTIONS peer index:"
                                  << i << std::endl;
                        break;
                    case ID_UNCONNECTED_PONG:
                        // Found the server
                        rakPeers[i]->Connect(
                            packet->systemAddress.ToString(false),
                            packet->systemAddress.GetPort(), 0, 0, 0
                        );
                        break;
                    case ID_CONNECTION_REQUEST_ACCEPTED:
                        // This tells the client they have connected
                        std::cout << "ID_CONNECTION_REQUEST_ACCEPTED peer index:"
                                  << i << std::endl;
                        break;
                    case ID_NEW_INCOMING_CONNECTION: {
                        clientCount--;
                        std::cout << "ID_NEW_INCOMING_CONNECTION peer index:"
                                  << i << "  clients to wait:" << clientCount
                                  << std::endl;
                                  
                        if (!clientCount) {
                            // If all clients are connected.
                            serverT = std::thread(
                                serverThread, mutex_.get(), &testValues,
                                &a[0], &c[0], &d[0], rpcPlugins[0],
                                peerCount, callCount
                            );
                            
                            serverT.detach();
                        }
                        break;
                    }
                    case ID_RPC_REMOTE_ERROR: {
                        // Recipient system returned an error
                        switch (packet->data[1]) {
                            case RakNet::RPC_ERROR_NETWORK_ID_MANAGER_UNAVAILABLE:
                                std::cout
                                    << "RPC_ERROR_NETWORK_ID_MANAGER_UNAVAILABLE"
                                    << " peer index:" << i << std::endl;
                                break;
                            case RakNet::RPC_ERROR_OBJECT_DOES_NOT_EXIST:
                                std::cout
                                    << "RPC_ERROR_OBJECT_DOES_NOT_EXIST peer index:"
                                    << i << std::endl;
                                break;
                            case RakNet::RPC_ERROR_FUNCTION_INDEX_OUT_OF_RANGE:
                                std::cout
                                    << "RPC_ERROR_FUNCTION_INDEX_OUT_OF_RANGE "
                                    << " peer index:" << i << std::endl;
                                break;
                            case RakNet::RPC_ERROR_FUNCTION_NOT_REGISTERED:
                                std::cout
                                    << "RPC_ERROR_FUNCTION_NOT_REGISTERED"
                                    << " peer index:" << i << std::endl;
                                break;
                            case RakNet::RPC_ERROR_FUNCTION_NO_LONGER_REGISTERED:
                                std::cout
                                    << "RPC_ERROR_FUNCTION_NO_LONGER_REGISTERED"
                                    << " peer index:" << i << std::endl;
                                break;
                            case RakNet::RPC_ERROR_CALLING_CPP_AS_C:
                                std::cout
                                    << "RPC_ERROR_CALLING_CPP_AS_C peer index:"
                                    << i << std::endl;
                                break;
                            case RakNet::RPC_ERROR_CALLING_C_AS_CPP:
                                std::cout
                                    << "RPC_ERROR_CALLING_C_AS_CPP peer index:"
                                    << i << std::endl;
                                break;
                        }
                        
                        std::cout << "Function: " << packet->data + 2
                                  << "     peer index:" << i << std::endl;
                        break;
                    }
                    default:
                        //std::cout << "Unknown id received: "
                        //            << packet->data[0] << std::endl;
                        break;
                }
            }
            
            //std::cout << "before" << std::endl;
            uint64_t allCount = (peerCount-1) * callCount;
            if (c[i].testCalls.size() < allCount ||
                c[i].testSlots.size() < allCount ||
                d[i].testSlots.size() < allCount ||
                cFuncTestCalls.size() < allCount) {
                /*std::cout << "in "
                      << "\n\tc[" << i << "].testCalls.size(): "
                      << c[i].testCalls.size()
                      << "\n\tc[" << i << "].testSlots.size(): "
                      << c[i].testSlots.size()
                      << "\n\td[" << i << "].testSlots.size(): "
                      << d[i].testSlots.size()
                      << "\n\tcFuncTestCalls.size(): "
                      << cFuncTestCalls.size()
                      << "\n\tallCount:              "
                      << allCount << std::endl;*/
                allready = false;
            }
        }

        RakSleep(0);
        
        if (allready) {
            mutex_->lock();
            testValues.allReady = true;
            mutex_->unlock();
        }
        
        allready = true;
    }

    testValues.programRunTime = RakNet::GetTimeUS() - programStartTime;
    testValues.AppendCFuncValues(cFuncTestCalls);
    
    for (size_t i = 1; i < peerCount; i++) {
        testValues.AppendCClassValues(c[i].testCalls);
        
        testValues.AppendCClassSlotValues(c[i].testSlots);
        testValues.AppendCClassSlotValues(d[i].testSlots);
    }
    
    testValues.PrintTestSummary();

    for (std::size_t i = 0; i < peerCount; i++) {
        delete rpcPlugins[i];
        rakPeers[i]->Shutdown(0, 0);
        RakNet::RakPeerInterface::DestroyInstance(rakPeers[i]);
    }
    rpcPlugins.clear();
    
    return 1;
}
Example #2
0
 void DoDomainLogic() {
   ClassC c = ClassC();
   c.DoSomething();
 }