0

ServerSocket着信クエリをリッスンするサーバー アプリケーションがあります。クエリを送信するクライアントは、サーバーへのソケットを開き、クエリを上流に渡し、(おそらく短時間の後に) クエリの送信に使用したのと同じソケットからクエリへの応答を読み取ることを期待しています。

このために、私はを使用しようとしていますExecutorCompletionService。さまざまなクエリ クラスがさまざまな に渡されますCallableが、すべてが結果として a を返すことが期待されStringます。

実際にクライアントに返信しようとする段階に達するまで、これらすべては非常に扱いやすいものです。現在、Futureオブジェクトはすべて typeFuture<String>ですが、その結果 ( String) を適切なに結合できませんSocket

私の解決策は、すべてのCallables を次のような型Callable<StringSocketPair>にすることです。StringSocketPair

public class StringSocketPair {
    Socket sock;
    String content;
}

しかし、これはすべて少し奇妙に思えます。コンストラクターに を渡してSocket、メソッドからの結果Callableと一緒にそれを返すことができるようにする必要があるからです。をポーリングするさらに別のスレッドにプッシュできるようにするためです。Stringcall()StringSocketExecutorCompletionService.take()

もう 1 つのオプションは、Runnables の代わりにCallables を使用し、各Runnableタスクを独自に応答させることですが、12 種類ほどのクエリ タイプがあるため、それぞれに独自のタスク オブジェクトがあり、いくつかの呼び出しSocketを追加する必要はありません。すべてのタスク オブジェクトrespondToClient()のすべてのメソッドの末尾に種類を設定します。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 に答える