Server folosind web sockets, modificat folosind o coada de joburi si un pool de thread-uri
Includem aici doua seturi de exemple:
WebServer si
ThreadPool
Pentru WebServer:
Sursele sunt:
- Handler.java
- WebServer.java
- TestClientWebServer.java
Dupa ce compilati WebServer.java si TestClientWebServer.java,
> Porniti mai intai programul WebServer
> Porniti dupa aceea programul TestClientWebServer
Pentru ThreadPool
Sursele sunt:
- JobQueueModel.java
- JobQueue.java
- ThreadPool.java
Se observa ca, pentru fiecare conexiune accesata, WebServer va creea un nou thread pe care se apeleaza
metoda process a lui Handler. Pentru a economisi resursele, preferam sa folosim un numar limitat de
thread-uri, pe care sa le initializam fie la inceput, fie pe masura ce apar job-uri.Pentru aceasta vom
folosi un pool de thread-uri, implementat ca (exemplu minimal) in ThreadPool.ThreadPool lucreaza impreuna
cu JobQueueModel (clasa abstracta); o implementare (nu neaparat corecta) este sugerata in JobQueue
WebServer, modificat in asa fel incat sa foloseasca un pool de thread-uri si o coada de job-uri, va functiona la
fel ca in implementarea curenta (cea experimentata de dumneavoastra la laborator).
TestWebClient poate ramane neschimbat.
Va trebui sa modificati:
- Handler;
- JobQueueModel;
- ThreadPool;
- WebServer
in asa fel incat:
- WebServer sa initializeze un pool de thread-uri in locul thread-urilor pe care se proceseaza request-ul de la TestWebClient acum;
- Pentru fiecare noua conexiune client acceptata de server se adauga un job in coada de joburi (folosind put());
- Oricare din thread-urile libere din pool-ul de thread-uri va lua urmatorul job din coada (folosind get() );
Tema de casa trebuie predata la 4 saptamani de la prezentarea ei.
Punctaj total tema de casa: 100 de puncte.
10p - puncte din oficiu;
70p - modificare WebServer, jobQueue, Handler, ThreadPool pentru a folosi un pool de thread-uri
20p - modificare program pentru a raporta thread-ul care opereaza un anume job.
Mai jos aveti sursele oferite ca punct de pornire (exemple folosite la curs si laborator)
File: Handler.java
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
public class Handler {
void process(Socket s) {
DataInputStream in = null;
DataOutputStream out = null;
try {
in = new DataInputStream(s.getInputStream());
out = new DataOutputStream(s.getOutputStream());
int request = in.readInt();
System.out.println("[SERVER HANDLER]: read from input stream: " + request);
int result = -request;
out.writeInt(result);
System.out.println("[SERVER HANDLER]: write to output stream: " + result);
}
catch (IOException ex) {}
finally {
try { if (in != null) in.close();
} catch(IOException ignore) {};
try { if (out != null) out.close();
} catch(IOException ignore) {};
try { s.close();
} catch(IOException ignore) {System.out.println("[SERVER HANDLER] Close port: Error closing port");};
}
}
}
File: WebServer.java
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class WebServer implements Runnable {
static final int PORT = 1040;
final int TIMEOUT = 30000;
Handler handler = new Handler();
ServerSocket socket = null;
public void run() {
try {
socket = new ServerSocket(PORT);
socket.setSoTimeout(TIMEOUT);
System.out.println("[SERVER]Socket: " + socket.getLocalPort() + " " + socket.getSoTimeout());
System.out.println("[SERVER] Web server started and waiting for requests ...");
while(true){
final Socket connection = socket.accept();
new Thread(new Runnable() {
public void run() {
System.out.println("[SERVER] N waiting for requests ...");
handler.process(connection);
}
}).start();
}
}
catch(Exception e){
e.printStackTrace();
}
}
public static void main (String args[]) throws IOException{
WebServer webServer = new WebServer();
webServer.run();
}
}
File: TestClientWebServer.java
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
public class TestClientWebServer {
static Socket socket = null;
static DataInputStream in = null;
static DataOutputStream out = null;
static int request = -1;
static int response = -1;
static final int PORT = 1040;
static final int REQ = 1024;
public static void main (String args[]) throws IOException {
request = REQ;
for(int i = 0; i < 3; i++) {
socket = new Socket("localhost",PORT);
try {
in = new DataInputStream(socket.getInputStream());
out = new DataOutputStream(socket.getOutputStream());
out.writeInt(request);
System.out.println("[CLIENT]: wrote to the output stream: " + request);
response = in.readInt();
System.out.println("[CLIENT]: read from the input stream: " + response);
request = response * (int)(10 * Math.random());
}
catch (IOException ex) {}
finally {
try { if (in != null) in.close();
} catch(IOException ignore) {};
try { if (out != null) out.close();
} catch(IOException ignore) {};
try { socket.close();
} catch(IOException ignore) {System.out.println("[SERVER HANDLER] Close port: Error closing port");};
}
}
}
}
File: JobQueueModel.java
public abstract class JobQueueModel {
abstract void put(Runnable r) throws InterruptedException;
abstract Runnable get() throws InterruptedException;
}
File: JobQueue.java
import java.util.Stack;
public class JobQueue extends JobQueueModel {
Stack jobQueue = new Stack();
final static int NO_ITEMS = 10;
@Override
void put(Runnable r) throws InterruptedException {
jobQueue.push(r);
}
@Override
Runnable get() throws InterruptedException {
if (!jobQueue.isEmpty())
return jobQueue.pop();
else
return null;
}
}
File: ThreadPool.java
interface Executor {
void execute(Runnable r);
}
public class ThreadPool implements Executor {
protected final JobQueueModel jobQueue;
public void execute(Runnable r) {
try {
jobQueue.put(r);
}
catch(InterruptedException ie) {
//postpone response
Thread.currentThread().interrupt();
}
}
public ThreadPool(JobQueueModel queue, int nWorkers) {
jobQueue = queue;
for(int i = 0; i < nWorkers; i++) {
activation();
}
}
protected void activation() {
Runnable rx = new Runnable() {
public void run() {
try {
while (true) {
Runnable r = (Runnable) (jobQueue.get());
r.run();
}
}
catch(InterruptedException ie) {} // ready
}
};
new Thread(rx).start();
}
public static void main (String args[]) {
JobQueue jobQueue = new JobQueue();
final int NO_OF_THREADS = 2;
new ThreadPool(jobQueue,NO_OF_THREADS);
}
}