私は現在、複数のクライアントが接続するサーバーを作成しています。通信プロトコルは、基本的にサーバーがクライアントにタスクを送信し、タスクが実行されたときにクライアントが応答するというものです。クライアントはサーバーへの接続を維持し、切断しないでください。
現在、各クライアントを処理するための新しいスレッドを開始しています。精神的には、私の現在のソリューションは次のようなものです:(実際にはJava同時実行からのソース)
public class ThreadPerTaskWebServer {
public static void main(String[] args) throws IOException {
ServerSocket socket = new ServerSocket(80);
while (true) {
final Socket connection = socket.accept();
Runnable task = new Runnable() {
public void run() {
handleRequest(connection);
}
};
new Thread(task).start();
}
}
private static void handleRequest(Socket connection) {
// request-handling logic here
}
}
しかし、エグゼキューターはより安定していて拡張性が高いように見えるので、エグゼキューターを使用したいと思います。したがって、サーバーがクライアントにメッセージを送信できるようにするには、クライアントを実行しているエグゼキューターとは別にクライアントを追跡する必要があります。したがって、クライアントをCopyOnWriteArrayListクライアントのどこに配置し、Serverクラスに次のようなものがある場合:
Socket clientSocket = serverSocket.accept();
// The runnable that takes care of a client
ClientHandler c = new ClientHandler(clientSocket, this);
// Start executing the ClientHandler
exec.execute(c);
// Add clients to CopyOnWriteArrayList
clients.add(c);
これにより、CopyOnWriteArrayListを反復処理して、すべてのクライアントにコマンドを送信し、切断されたクライアントを削除することができます。これは堅牢なソリューションでしょうか?何らかの理由でランナブルが例外を伝播した場合、エグゼキュータはどうなりますか?