如何向Java映射添加对

如何向Java映射添加对,java,networking,client-server,thrift,Java,Networking,Client Server,Thrift,这是我在StackOverflow上的第一个线程,请耐心等待 从一个简单的thrift服务开始,我想创建一个java客户机/服务器应用程序,其中每个节点向分布式计算系统中的其他节点提供一个或多个服务。我想从一个简单的系统开始,在这个系统中,每个节点都有两个字符串,“hostname”和“servicename”,它们相互标识。我创建了这个类: class NodePort <Node, integer> { private Node node; private int por

这是我在StackOverflow上的第一个线程,请耐心等待

从一个简单的thrift服务开始,我想创建一个java客户机/服务器应用程序,其中每个节点向分布式计算系统中的其他节点提供一个或多个服务。我想从一个简单的系统开始,在这个系统中,每个节点都有两个字符串,“hostname”和“servicename”,它们相互标识。我创建了这个类:

class NodePort <Node, integer> {
  private Node node;
  private int port;

  NodePort(Node node, int port) {
    this.node = node;
    this.port = port;
  }

  Node getNode() {
    return node;
  }

  int getPort() {
    return port;
  }
}
使用NodeRegister时,服务器将创建一个映射,其中键由ServiceName提供,值为NodePorts,并返回客户端使用的端口

使用getNodeForService时,它应该返回客户端注册的映射中存在的服务列表

我不确定如何编写这两种方法的实现。我写过这篇文章,但当我尝试测试时,它不起作用:

import org.apache.thrift.TException;

import it.uniud.atta.profiling.thrift.ManagementService;

public class ManagementServiceImpl implements ManagementService.Iface {

  public int NodeRegister(int port) throws TException {
    return port;
  }

  public Node getNodeForService(Node node) throws TException {
    return node;
  }
}
我很确定这不是我想要的方式,而且我真的不知道把地图代码放在哪里。我怎样才能继续

提前感谢您的帮助

编辑:我正在添加我的“用问题回答问题”帖子的内容。对不起,下次我会更好地阅读规则的

我实际上需要帮助编写测试文件。到目前为止,我已经创建了一个标准的thrift服务器和一个thrift客户端,它监听一个端口。代码如下:

public class ManagementServiceTest {

public static class Server implements Runnable {

private TServer tserver;

  public void run() {
      try {
           TServerSocket serverTransport = new TServerSocket(7911);

           ManagementService.Processor<ManagementServiceHandler> processor = new      ManagementService.Processor<ManagementServiceHandler>(new ManagementServiceHandler());

           tserver = new TThreadPoolServer(new TThreadPoolServer.Args(serverTransport).
                    processor(processor));
           System.out.println("Starting server on port 7911 ...");
           tserver.serve();
          } catch (TTransportException e) {
              e.printStackTrace();
          }
   }

  public void start() {
    new Thread(this).start();
  }

  public void unserve() {
    tserver.stop();
  } 
}

@Test
public void testServerCompletion() {
    Server server = new Server();
    server.start();

    TTransport transport;
    try {

        Thread.sleep(200);
            transport = new TSocket("localhost", 7911);
            TProtocol protocol = new TBinaryProtocol(transport);

            ManagementService.Client client = new ManagementService.Client(protocol);
            transport.open();



//          client.getNodes(testNode.hostName, testNode.serviceName);
//          System.out.println("Servizi disponibili: " + testNode.serviceName);
//            
//          for (String key: nodes.keySet()) {
//
//                System.out.println("key : " + key);
//                System.out.println("value : " + nodes.get(key));            

            transport.close();

            server.unserve();   
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
但它返回“类型管理服务中的方法RegisterNode(Node,int)。客户端不适用于参数(String,int)”

所以我试过了

Node node1;
node1 = client.RegisterNode(node1, 1025);
但它返回“类型不匹配:无法从int转换为Node”

我还没有尝试过其他方法,但我想我会收到类似的错误

我不确定我是否理解如何编写测试文件。。。有什么提示吗

编辑:好的,我已经设法解决了这个问题:

int port = 0;
Node node1 = new Node();
node1.hostname = "Node 1";
node1.serviceName = "Hello World Service";
port = client.RegisterNode(node1, 1025);
System.out.println("Node hostname: " + node1.hostName + "Node Port Used: " + port);
它确实返回节点的名称和使用的端口

现在,第二个方法getNodes()也提出了一些问题。我用这个:

Nodes nodes = new Nodes();
client.getNodes(node1.hostName, node1.serviceName);
System.out.println("Servizi disponibili: " + node1.serviceName);

for (String key: nodes.keySet()) {

  System.out.println("key : " + key);
  System.out.println("value : " + nodes.get(key));    
}

但它返回两个错误,即没有为tyoe节点定义keySet()和get()方法。我不确定该如何继续…

我会以不同的方式构建服务,如下所示:

struct Node {
  1: string hostName,
  2: string serviceName,
}

struct Nodes {
  1: map<Node, i32>  allNodes
}

service ManagementService {
  /** registers a node to a server, returning the port used */
  i32 RegisterNode(1 : Node hostAndService, 2 : i32 preferredPort)

  /** lists all the services available at the moment. 
      Optionally specify host and/or service name to narrow the search */
  Nodes GetNodes(1: string host, 2: string service)
}

“不起作用”到底是什么意思?如果每次有人给我一美元作为唯一的错误描述。。。那么,请问:当您尝试什么时,您预期会发生什么?谢谢您的回答。Eclipse在我为测试代码而编写的测试文件中返回错误,在我调用两个方法NodeRegister()和getNodeForService()的行中,表示该方法对于ManagementServiceTest类型是未定义的(这是测试文件的名称)。实际上我已经解决了这个问题,但现在还有另一个问题。我已经编写了一个测试服务器和客户端文件,该文件应该使用端口1025使用serviceName“sum”注册名为node1的节点。我在映射中添加了一个条目,该条目使用字符串作为键(它将是serviceName,sum),和一个NodePort作为值。Eclipse告诉我类型映射中的方法put(String,NodePort)不适用于参数(Node,int)。我不知道错误在哪里…
GetNodes()
返回一个
Nodes
类型(下面IDL中的结构)它包含一个成员
allNodes
。这个
Map allNodes
成员实际上就是要迭代的映射。为什么把它放在一个结构中更好呢?一个词:flexibility。如果需要的话,这样你可以在以后扩展返回的数据。我还建议你看看代码。我们有一个很好的教程。所以实现RegisterNode()的定义类似于:RegisterNode(Node hostAndService,int preferredPort){Map Map Map=new HashMap;}?不过我不确定应该如何实现GetNodes()。感谢这个示例,我正在研究它。不过我必须检查几件事:1)var在java中不存在,所以我不得不删除它并使用完整的类型名;2) 我不得不把所有的“add”改为“put”)。此外,还有一个问题,因为eclipse一直告诉我“类型ManagementServiceHandler必须实现继承的抽象方法ManagementService.Iface.getNodes(String,String)”,但该方法存在。一种解决方案是使ManagementServiceHandler抽象,另一种方法是使getNodes()方法返回null。我觉得这两个都不对。我该怎么办?发现问题,只是方法的名称错误(GetNodes而不是GetNodes)。现在我必须研究迭代器,因为根据eclipse,它有一些问题。。。1) “键无法解析或不是字段”和“2”只能在“for”行中“for(Nodes:Nodes)”迭代java.lang.Iterable的数组或实例。我需要在那里换些东西。无论如何,非常感谢你的帮助!您可以随时要求、投票或接受;-)
Nodes nodes = new Nodes();
client.getNodes(node1.hostName, node1.serviceName);
System.out.println("Servizi disponibili: " + node1.serviceName);

for (String key: nodes.keySet()) {

  System.out.println("key : " + key);
  System.out.println("value : " + nodes.get(key));    
}
struct Node {
  1: string hostName,
  2: string serviceName,
}

struct Nodes {
  1: map<Node, i32>  allNodes
}

service ManagementService {
  /** registers a node to a server, returning the port used */
  i32 RegisterNode(1 : Node hostAndService, 2 : i32 preferredPort)

  /** lists all the services available at the moment. 
      Optionally specify host and/or service name to narrow the search */
  Nodes GetNodes(1: string host, 2: string service)
}
public static class ManagementServiceHandler implements ManagementService.Iface {

    private Map<Node,int> nodes;

    public ManagementServiceHandler() 
    {
        nodes = new Map<Node,int>()
    }

    /**
     * registers a node to a server, returning the port used
     */
    public int RegisterNode(Node hostAndService, int preferredPort) {
        int port = preferredPort;
        // TODO: check whether port can be used
        nodes.Add( hostAndService, port);
        return port;    
    }

    /**
     * lists all the services available at the moment.
     * Optionally specify host and/or service name to narrow the search
     */
    public Nodes GetNodes(String host, String svcname)  {
        var Nodes retval = new Nodes();
        retval.allNodes = new Map<Node,int>();

        for( var node : nodes) {
            if( (host.isEmpty() || (host == node.key.host)) {
                if( (svcname.isEmpty() || (svcname == node.key.serviceName)) {
                    retval.allNodes.add(node)
                }
            }
        }

        return retval;
    }
}