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