【发布时间】:2014-04-08 21:20:05
【问题描述】:
这是我在 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;
}
}
然后,我编写了一个管理节俭服务,它做了两件事:
1) 向服务器注册一个节点,返回使用的端口
2) 列出当前可用的所有服务
typedef i32 int
struct Node {
1: string hostName,
2: string serviceName,
}
service ManagementService {
int NodeRegister(i32 port)
Node getNodeForService(Node node)
}
使用 NodeRegister 时,服务器会创建一个 Map,其中键由 serviceNames 给出,值是 NodePorts,并返回客户端使用的端口。
使用 getNodeForService 时,它应该返回客户端注册的 Map 中存在的服务列表。
我不确定如何编写这两种方法的实现。我已经写了这个,但是当我尝试测试时它不起作用:
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();
}
}
}
我不确定在 transport.open() 行之后我必须写什么。现在,我应该在端口 7911 上打开一个服务器并进行监听,一个打开的传输和一个需要初始化的未使用的客户端变量。我想使用 RegisterNode() 方法和 getNodes() 方法,但到目前为止我所有的尝试都没有成功。我试过了:
Node node1;
node1 = client.RegisterNode(1025);
但它返回“ManagementService.Client 类型中的方法 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));
}
但它返回两个关于 keySet() 和 get() 方法没有为 tyoe 节点定义的错误。我不确定我应该如何进行...
【问题讨论】:
-
“不起作用”究竟是什么意思?如果每次有人将此作为唯一的错误描述时我得到一美元......那么请:你期望什么,当你尝试什么时会发生什么?
-
感谢您的回答。Eclipse 在我为测试代码而编写的测试文件中返回错误,在我调用 NodeRegister() 和 getNodeForService() 这两个方法的行中,说未定义 ManagementServiceTest 类型的方法(这是测试文件的名称)。
-
实际上我已经解决了这个问题,但现在还有另一个问题。我已经编写了一个测试服务器和客户端文件,该文件应该使用端口 1025 使用 serviceName“sum”注册一个名为 node1 的节点。我在使用字符串作为键的 Map 中添加了一个条目(它将是 serviceName,sum),和一个 NodePort 作为值。 Eclipse 告诉我 Map
类型中的 put(String, NodePort) 方法不适用于参数 (Node, int)。我不明白错误在哪里...... -
GetNodes()返回一个Nodes类型(来自下面的 IDL 的结构),其中包含一个成员allNodes。这个Map<Node,Integer> allNodes成员其实就是要迭代的map。为什么将其放入结构中更好?一个词:灵活。这样,您可以在以后根据需要扩展返回的数据。 -
我还建议您查看Thrift Java tutorial 代码。我们真的有一个很好的教程。
标签: java networking client-server thrift