nameserver.cpp

来自「一个语言识别引擎」· C++ 代码 · 共 681 行 · 第 1/2 页

CPP
681
字号

    String result = "Here are some ways to use the name server:\n";
    ACE_Vector<String> names = dispatcher.getNames();
    for (unsigned i=0; i<names.size(); i++) {
        const String& name = names[i];
        result += String("  NAME_SERVER ") + name + " ...\n";
    }
    return terminate(result);
}


String NameServer::cmdSet(int argc, char *argv[]) {
    // ignore source
    argc--;
    argv++;

    if (argc<2) {
        return "need at least two arguments: the port name, and a key";
    }
    String target = argv[0];
    String key = argv[1];
    NameRecord& nameRecord = getNameRecord(target);
    nameRecord.clearProp(key);
    for (int i=2; i<argc; i++) {
        nameRecord.addProp(key,argv[i]);
    }
    return terminate(String("port ") + target + " property " + key + " = " +
                     nameRecord.getProp(key) + "\n");
}

String NameServer::cmdGet(int argc, char *argv[]) {
    // ignore source
    argc--;
    argv++;

    if (argc<2) {
        return "need exactly two arguments: the port name, and a key";
    }
    String target = argv[0];
    String key = argv[1];
    NameRecord& nameRecord = getNameRecord(target);
    return terminate(String("port ") + target + " property " + key + " = " +
                     nameRecord.getProp(key) + "\n");
}

String NameServer::cmdMatch(int argc, char *argv[]) {
    // ignore source
    argc--;
    argv++;

    if (argc<3) {
        return "need exactly three arguments: the port name, a key, and a prefix";
    }
    String target = argv[0];
    String key = argv[1];
    String prefix = argv[2];
    NameRecord& nameRecord = getNameRecord(target);
    return terminate(String("port ") + target + " property " + key + " = " +
                     nameRecord.matchProp(key,prefix) + "\n");
}

String NameServer::cmdCheck(int argc, char *argv[]) {
    // ignore source
    argc--;
    argv++;

    if (argc<2) {
        return "need at least two arguments: the port name, and a key";
    }
    String response = "";
    String target = argv[0];
    String key = argv[1];
    NameRecord& nameRecord = getNameRecord(target);
    for (int i=2; i<argc; i++) {
        String val = "false";
        if (nameRecord.checkProp(key,argv[i])) {
            val = "true";
        }
        if (i>2) {
            response += "\n";
        }
        response += "port " + target + " property " + 
            key + " value " + argv[i] + " present " + val;
    }
    response += "\n";
    return terminate(response);
}


String NameServer::cmdList(int argc, char *argv[]) {
    String response = "";

    for (NameMapHash::iterator it = nameMap.begin(); it!=nameMap.end(); it++) {
        NameRecord& rec = (*it).int_id_;
        response += textify(rec.getAddress());
    }

    return terminate(response);
}



String NameServer::textify(const Address& address) {
    String result = "";
    if (address.isValid()) {
        result = "registration name ";
        result = result + address.getRegName() + 
            " ip " + address.getName() + " port " + 
            NetType::toString(address.getPort()) + " type " + 
            address.getCarrierName() + "\n";
    }
    return result;
}


String NameServer::terminate(const String& str) {
    return str + "*** end of message";
}


String NameServer::apply(const String& txt, const Address& remote) {
    String result = "no command given";
    mutex.wait();
    try {
        SplitString ss(txt.c_str());
        if (ss.size()>=2) {
            String key = ss.get(1);
            YARP_DEBUG(Logger::get(),String("dispatching to ") + key);
            ss.set(1,remote.getName().c_str());
            result = dispatcher.dispatch(this,key.c_str(),ss.size()-1,
                                         (char **)(ss.get()+1));
            YARP_DEBUG(Logger::get(), String("name server request -- ") + txt);
            YARP_DEBUG(Logger::get(), String("name server result  -- ") + result);
        }
    } catch (IOException e) {
        YARP_DEBUG(Logger::get(),String("name server sees exception ") + 
                   e.toString());
        mutex.post();
        throw e;
    }
    mutex.post();
    return result;
}





#ifndef DOXYGEN_SHOULD_SKIP_THIS

class MainNameServer : public NameServer, public Readable {

public:
    MainNameServer(int basePort) {
        this->basePort = basePort;
    }

    virtual bool read(ConnectionReader& reader) {
        ManagedBytes header(12);
        for (int i0=0; i0<header.length(); i0++) {
            header.get()[i0] = '\0';
        }
        reader.expectBlock(header.bytes().get(),header.bytes().length());
        YARP_DEBUG(Logger::get(),"name server got something");
        String ref = "NAME_SERVER ";
        bool ok = true;
        for (int i=0; i<header.length(); i++) {
            if (header.get()[i] != ref[i]) {
                ok = false; 
                break;
            }
        }
        if (header.get()[0] == '\0') {
            return false;
        }
        String msg = "?";
        if (ok) {
            msg = ref + reader.expectText().c_str();
        }
        YARP_DEBUG(Logger::get(),String("name server got message ") + msg);
        int index = msg.find("NAME_SERVER");
        if (index==0) {
            Address remote;
            remote = Address::fromContact(reader.getRemoteContact());
            //if (reader.getStreams()!=NULL) {
            //remote = reader.getStreams()->getRemoteAddress();
            //}
            YARP_DEBUG(Logger::get(),String("name server receiving from ") + 
                       remote.toString());
            YARP_DEBUG(Logger::get(),String("name server request is ") + msg);
            String result = apply(msg,remote);
            //OutputStream *os = reader.getReplyStream();
            ConnectionWriter *os = reader.getWriter();
            if (os!=NULL) {
                if (result=="") {
                    result = terminate(String("unknown command ") + msg + "\n");
                }
                //os->writeLine(result);
                //os->flush();
                //os->close();

                // This change is just to make Microsoft Telnet happy
                String tmp;
                for (unsigned int i=0; i<result.length(); i++) {
                    if (result[i]=='\n') {
                        tmp += '\r';
                    }
                    tmp += result[i];
                }
                tmp += '\r';
                os->appendString(tmp.c_str(),'\n');
                //os->appendString(result.c_str(),'\n');
	
                YARP_DEBUG(Logger::get(),String("name server reply is ") + result);
                String resultSparse = result;
                int end = resultSparse.find("\n*** end of message");
                if (end>=0) {
                    resultSparse[end] = '\0';
                }
                YARP_INFO(Logger::get(),resultSparse);
            }
        } else {
            YARP_INFO(Logger::get(),"Name server ignoring unknown command: "+msg);
            //OutputStream *os = reader.getReplyStream();
            ConnectionWriter *os = reader.getWriter();
            if (os!=NULL) {
                // this result is necessary for YARP1 support
                os->appendString("???????????????????????????????????????",'\n');
                //os->flush();
                //os->close();
            }
        }
        return true;
    }
};


#endif /* DOXYGEN_SHOULD_SKIP_THIS */



int NameServer::main(int argc, char *argv[]) {

    // pick an address
    Address suggest("...",0); // suggestion is initially empty

    try {

        if (argc>=1) {
            if (argc>=2) {
                suggest = Address(argv[0],NetType::toInt(argv[1]));
            } else {
                suggest = Address("...",NetType::toInt(argv[0]));
            }
        }
    
        // see what address is lying around
        Address prev;
        NameConfig conf;
        if (conf.fromFile()) {
            prev = conf.getAddress();
        }
    
        // merge
        if (prev.isValid()) {
            if (suggest.getName()=="...") {
                suggest = Address(prev.getName(),suggest.getPort());
            }
            if (suggest.getPort()==0) {
                suggest = Address(suggest.getName(),prev.getPort());
            }
        }
    
        // still something not set?
        if (suggest.getPort()==0) {
            suggest = Address(suggest.getName(),10000);
        }
        if (suggest.getName()=="...") {
            // should get my IP
            suggest = Address(conf.getHostName(),suggest.getPort());
        }
    
        // finally, should make sure IP is local, and if not, correct it
        if (!conf.isLocalName(suggest.getName())) {
            YARP_INFO(Logger::get(),"Overriding non-local address for name server");
            suggest = Address(conf.getHostName(),suggest.getPort());
        }
    
        // and save
        conf.setAddress(suggest);
        if (!conf.toFile()) {
            YARP_ERROR(Logger::get(), String("Could not save configuration file ") +
                       conf.getConfigFileName());
        }
    
        PortCore server;  // we use a subset of the PortCore functions
        MainNameServer name(suggest.getPort() + 2);

        // register root for documentation purposes
        name.registerName("root",suggest.addCarrier("text"));
        server.setReadHandler(name);
        server.setAutoHandshake(false);
        server.listen(Address(suggest.addRegName("root")));
        YARP_INFO(Logger::get(), String("Name server listening at ") + 
                  suggest.toString());
        server.start();
    
        FallbackNameServer fallback(name);
        fallback.start();

        // register fallback root for documentation purposes
        name.registerName("fallback",FallbackNameServer::getAddress());
        YARP_INFO(Logger::get(), String("Bootstrap server listening at ") + 
                  FallbackNameServer::getAddress().toString());
    
        while (true) {
            YARP_DEBUG(Logger::get(),"name server running happily");
            Time::delay(60);
        }
        server.close();
        fallback.close();
        fallback.join();
    
    } catch (IOException e) {
        YARP_DEBUG(Logger::get(),e.toString() + " <<< name server exception");
        YARP_ERROR(Logger::get(), "name server failed to start");
        YARP_ERROR(Logger::get(), String("   reason for failure is \"") + 
                   e.toString() + "\"");
        YARP_ERROR(Logger::get(), "   the name server may already be running?");
        if (suggest.getPort()>0) {
            YARP_ERROR(Logger::get(), String("   or perhaps another service may already be running on port ") + NetType::toString(suggest.getPort()) + "?");
        }
        return 1;
    }

    return 0;
}


⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?