From a53b273411b7ae5c13588b615161e74054066615 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jan=20Ko=C5=BEusznik?= <jan@kozusznik.cz>
Date: Tue, 22 Mar 2022 09:22:29 +0100
Subject: [PATCH] Implement selector.

---
 src/main/java/lab07/HttpHandler.java | 10 ++++++
 src/main/java/lab07/Main.java        | 49 ++++++++++++++++++++++------
 2 files changed, 49 insertions(+), 10 deletions(-)

diff --git a/src/main/java/lab07/HttpHandler.java b/src/main/java/lab07/HttpHandler.java
index b4da84e..0003512 100644
--- a/src/main/java/lab07/HttpHandler.java
+++ b/src/main/java/lab07/HttpHandler.java
@@ -1,5 +1,7 @@
 package lab07;
 
+import static jakarta.ws.rs.core.Response.Status.OK;
+
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.RandomAccessFile;
@@ -23,10 +25,13 @@ class HttpHandler {
 	
 	private final Path root;
 	
+	private final StringBuilder requests = new StringBuilder();
+	
 	void handle(SocketChannel channel) {
 		String request;
 		try {
 			request = getRequest(channel);
+			requests.append(request);
 			String resource = getResource(request);
 			CompletableFuture<Void> future = transferFile(resource, channel);
 			//task: #3
@@ -40,6 +45,11 @@ class HttpHandler {
 		}
 	}
 	
+	public void handleObserverChannel(SocketChannel accept) {
+		writeStatus(OK, accept);
+		writeString(requests.toString(), accept);
+	}
+
 	private void close(SocketChannel channel) {
 		try {
 			channel.close();
diff --git a/src/main/java/lab07/Main.java b/src/main/java/lab07/Main.java
index a824c5b..f2dc2de 100644
--- a/src/main/java/lab07/Main.java
+++ b/src/main/java/lab07/Main.java
@@ -3,10 +3,12 @@ package lab07;
 import java.io.IOException;
 import java.net.InetSocketAddress;
 import java.net.URISyntaxException;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.Selector;
 import java.nio.channels.ServerSocketChannel;
-import java.nio.channels.SocketChannel;
 import java.nio.file.Path;
 import java.nio.file.Paths;
+import java.util.Iterator;
 
 import lombok.extern.log4j.Log4j2;
 
@@ -16,15 +18,42 @@ public class Main {
 		int port = 8000;
 		String basePathName = "..";
 		Path basePath = Paths.get(basePathName).toRealPath();
-		log.info("Started server on http://localhost:{} with base path {}", port, basePath);
-		HttpHandler handler = new HttpHandler(Paths.get("."));
-		ServerSocketChannel ssc = ServerSocketChannel.open();
-		ssc.bind(new InetSocketAddress(8000));
-		
-		while(true) {
-			SocketChannel sc = ssc.accept();
-			handler.handle(sc);
+		log.info("Started server on http://localhost:{} with base path {} and on http://localhost:{}", port, basePath, port + 1);
+		HttpHandler handler = new HttpHandler(Paths.get(basePathName));
+		try(ServerSocketChannel ssc = ServerSocketChannel.open();ServerSocketChannel ssc2 = ServerSocketChannel.open()){
+			ssc.bind(new InetSocketAddress(port));
+			ssc.configureBlocking(false);
+			
+			ssc2.bind(new InetSocketAddress(port + 1));
+			ssc2.configureBlocking(false);
+			
+			//task #4 - handle two channels with selector 
+			try(Selector selector = Selector.open())
+			{
+				ssc.register(selector, SelectionKey.OP_ACCEPT);
+				ssc2.register(selector, SelectionKey.OP_ACCEPT);
+				
+				while(true) {
+					if(0 == selector.select()) {
+						break;
+					}
+					Iterator<SelectionKey> keys = selector.selectedKeys().iterator();
+					while (keys.hasNext()) {
+						SelectionKey key = keys.next();
+						if (key.interestOps() == SelectionKey.OP_ACCEPT) {
+							if (key.channel() == ssc) {
+								handler.handle(ssc.accept());
+							}
+							
+							if (key.channel() == ssc2) {
+								handler.handleObserverChannel(ssc2.accept());
+							}
+						}
+						keys.remove();
+					}
+				}
+			}
 		}
-		//ssc.close();
+		
 	}
 }
-- 
GitLab