nameserver.cpp

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

CPP
681
字号
// -*- mode:C++; tab-width:4; c-basic-offset:4; indent-tabs-mode:nil -*-

/*
 * Copyright (C) 2006 Paul Fitzpatrick
 * CopyPolicy: Released under the terms of the GNU GPL v2.0.
 *
 */


#include <yarp/NameServer.h>
#include <yarp/Logger.h>
#include <yarp/PortCore.h>
#include <yarp/os/Time.h>
#include <yarp/SplitString.h>
#include <yarp/NetType.h>
#include <yarp/ManagedBytes.h>
#include <yarp/NameConfig.h>
#include <yarp/FallbackNameServer.h>

using namespace yarp;
using namespace yarp::os;



////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
//
// Basic functionality
//
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////


Address NameServer::unregisterName(const String& name) {
    Address prev = queryName(name);
    if (prev.isValid()) {
        if (prev.getPort()!=-1) {
            NameRecord& rec = getNameRecord(prev.getRegName());
            if (rec.isReusablePort()) {
                HostRecord& host = getHostRecord(prev.getName());
                host.release(prev.getPort());
            }
            //NameRecord& rec = getNameRecord(name);
            rec.clear();
            tmpNames.release(name);
        }
    }
  
    return queryName(name);
}



Address NameServer::registerName(const String& name, 
                                 const Address& address,
                                 const String& remote) {
    bool reusablePort = false;

    YARP_DEBUG(Logger::get(),"in registerName...");

    if (name!="...") {
        unregisterName(name);
    }

    Address suggestion = address;

    if (!suggestion.isValid()) {
        suggestion = Address("...",0,"...",name);
    }

    String portName = name;
    if (portName == "...") {
        portName = tmpNames.get();
    }

    String carrier = suggestion.getCarrierName();
    if (carrier == "...") {
        carrier = "tcp";
    }

    String machine = suggestion.getName();
    if (machine == "...") {
        if (carrier!="mcast") {
            if (remote=="...") {
                YARP_ERROR(Logger::get(),"remote machine name was not found!  can only guess it is local...");
                machine = "localhost";
            } else {
                machine = remote; 
            }
        } else {
            machine = mcastRecord.get();
        }
    }

    int port = suggestion.getPort();
    if (port == 0) {
        port = getHostRecord(machine).get();
        reusablePort = true;
    }

    suggestion = Address(machine,port,carrier,portName);

    YARP_DEBUG(Logger::get(),String("Thinking about registering ") +
               suggestion.toString());
  
    NameRecord& nameRecord = getNameRecord(suggestion.getRegName());
    nameRecord.setAddress(suggestion,reusablePort);

    return nameRecord.getAddress();
}


Address NameServer::queryName(const String& name) {
    String base = name;
    String pat = "";
    if (name.strstr("/net=") == 0) {
        int patStart = 5;
        int patEnd = name.find('/',patStart);
        if (patEnd>=patStart) {
            pat = name.substr(patStart,patEnd-patStart);
            base = name.substr(patEnd);
            YARP_DEBUG(Logger::get(),String("Special query form ") +
                       name + " (" + pat + "/" + base + ")");
        }
    }

    NameRecord *rec = getNameRecord(base,false);
    if (rec!=NULL) {
        if (pat!="") {
            String ip = rec->matchProp("ips",pat);
            if (ip!="") {
                SplitString sip(ip.c_str());
                return (rec->getAddress()).addName(sip.get(0));
            }
        }
        return rec->getAddress();
    }
    return Address();
}


NameServer::NameRecord *NameServer::getNameRecord(const String& name, 
                                                  bool create) {
    ACE_Hash_Map_Entry<String,NameRecord> *entry = NULL;
    int result = nameMap.find(name,entry);
    if (result==-1) {
        if (!create) {
            return NULL;
        }
        nameMap.bind(name,NameRecord());
        result = nameMap.find(name,entry);
    }
    YARP_ASSERT(result!=-1);
    YARP_ASSERT(entry!=NULL);
    return &(entry->int_id_);
}


NameServer::HostRecord *NameServer::getHostRecord(const String& name,
                                                  bool create) {
    ACE_Hash_Map_Entry<String,HostRecord> *entry = NULL;
    int result = hostMap.find(name,entry);
    if (result==-1) {
        if (!create) {
            return NULL;
        }
        hostMap.bind(name,HostRecord());
        result = hostMap.find(name,entry);
        YARP_ASSERT(entry!=NULL);
        entry->int_id_.setBase(basePort);
    }
    YARP_ASSERT(result!=-1);
    YARP_ASSERT(entry!=NULL);
    return &(entry->int_id_);
}









////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
//
// Remote interface
//
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////



void NameServer::setup() {

    basePort = 10002; // this gets replaced

    dispatcher.add("register", &NameServer::cmdRegister);
    dispatcher.add("unregister", &NameServer::cmdUnregister);
    dispatcher.add("query", &NameServer::cmdQuery);
    dispatcher.add("help", &NameServer::cmdHelp);
    dispatcher.add("set", &NameServer::cmdSet);
    dispatcher.add("get", &NameServer::cmdGet);
    dispatcher.add("check", &NameServer::cmdCheck);
    dispatcher.add("match", &NameServer::cmdMatch);
    dispatcher.add("list", &NameServer::cmdList);
    dispatcher.add("route", &NameServer::cmdRoute);
}

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

    String remote = argv[0];
    argc--;
    argv++;

    if (argc<1) {
        return "need at least one argument";
    }
    String portName = argv[0];

    String machine = "...";
    String carrier = "...";
    int port = 0;
    if (argc>=2) {
        carrier = argv[1];
    }
    if (argc>=3) {
        machine = argv[2];
    }
    if (argc>=4) {
        if (String("...") == argv[3]) {
            port = 0;
        } else {
            port = NetType::toInt(argv[3]);
        }
    }

    Address address = registerName(portName,
                                   Address(machine,port,carrier,portName),
                                   remote);

    YARP_DEBUG(Logger::get(), 
               String("name server register address -- ") +
               address.toString());
  
    return terminate(textify(address));
}


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

    if (argc<1) {
        return "need at least one argument";
    }
    String portName = argv[0];
    Address address = queryName(portName);
    return terminate(textify(address));
}

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

    if (argc<1) {
        return "need at least one argument";
    }
    String portName = argv[0];
    Address address = unregisterName(portName);
    return terminate(textify(address));
}


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

    if (argc<2) {
        return terminate("need at least two arguments: the source port and the target port\n(followed by an optional list of carriers in decreasing order of desirability)");
    }
    String src = argv[0];
    String dest = argv[1];

    argc-=2;
    argv+=2;

    char *altArgv[] = { "local", "shmem", "mcast", "udp", "tcp", "text" };
    int altArgc = 6;

    if (argc==0) {
        argc = altArgc;
        argv = altArgv;
    }


    NameRecord& srcRec = getNameRecord(src);
    NameRecord& destRec = getNameRecord(dest);
    String pref = "";

    for (int i=0; i<argc; i++) {
        String carrier = argv[i];
        if (srcRec.checkProp("offers",carrier) &&
            destRec.checkProp("accepts",carrier)) {
            bool ok = true;
            if (carrier=="local"||carrier=="shmem") {
                if (srcRec.getProp("ips") == destRec.getProp("ips")) {
                    if (carrier=="local") {
                        if (srcRec.getProp("process") != destRec.getProp("process")) {
                            ok = false;
                        }
                    }
                } else {
                    ok = false;
                }
            }
            if (ok) {
                pref = carrier;
                break;
            }
        }
    }
    if (pref!="") {
        pref = pref + ":/" + dest;
    } else {
        pref = dest;
    }

    String result = "port " + src + " route " + dest + " = " + pref + "\n";
    return terminate(result);
}


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

⌨️ 快捷键说明

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