0

我有一个服务器应用程序,它监听ServerSocket传入的查询。提交查询的客户端希望打开一个到服务器的套接字,将他们的查询传递到上游,然后(可能在很短的一段时间后)从他们用来提交查询的同一个套接字读取对其查询的响应。

为此,我正在尝试使用ExecutorCompletionService. 不同的查询类被传递给不同Callable的 s,但都期望返回 aString作为它们的结果。

在我达到实际尝试回复客户的阶段之前,所有这些都是可以管理的。这些Future对象目前都是 type Future<String>,但我无法将该结果(the String)与适当的Socket.

我的解决方案是让我所有的Callables 都是看起来像Callable<StringSocketPair>的类型;StringSocketPair

public class StringSocketPair {
    Socket sock;
    String content;
}

但这一切似乎有点奇怪,因为现在我必须将 传递SocketCallable构造函数,以便它可以将它与方法的String结果一起返回call()。所有这些都是为了让我可以将其推String送到Socket另一个轮询线程中ExecutorCompletionService.take()

另一种选择是使用Runnables 而不是Callables 并让每个Runnable任务自己响应Socket,但是由于我有十几种查询类型,每个都有自己的任务对象,我宁愿不必添加respondToClient()一些调用kind 到run()每个任务对象的每个方法的末尾。

对于我认为相当常见的设置,必须有一个更简单的解决方案?

4

1 回答 1

2

按照使用 的想法Runnable,您可以使用模板方法模式来定义响应功能。这将防止您必须为每个任务编写公共代码,因为公共代码将放置在实现 Runnable 的抽象父类中。

模板方法模式:

abstract class TemplateSuperClass implements Runnable {
    public void run() {
        //some setup code here
        String message = taskWork(...);
        socket.write(message);
        //common cleanup code
    }

    abstract String taskWork(...);
}

class HelloWorld extends TemplateSuperClass {
    String taskWork(...) {
        return "Hello World";
    }
}

否则,您可能正确地更改 Callable 以返回响应消息和套接字的元组。

于 2012-11-16T20:09:54.293 回答