You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
207 lines
8.0 KiB
207 lines
8.0 KiB
/*
|
|
* To change this license header, choose License Headers in Project Properties.
|
|
* To change this template file, choose Tools | Templates
|
|
* and open the template in the editor.
|
|
*/
|
|
package robotindex;
|
|
|
|
import java.io.BufferedOutputStream;
|
|
import java.io.BufferedReader;
|
|
import java.io.FileNotFoundException;
|
|
import java.io.IOException;
|
|
import java.io.InputStreamReader;
|
|
import java.io.OutputStream;
|
|
import java.io.PrintWriter;
|
|
import java.net.ServerSocket;
|
|
import java.net.Socket;
|
|
import java.util.Date;
|
|
import java.util.StringTokenizer;
|
|
|
|
/**
|
|
*
|
|
* @author arthurdambrine
|
|
*/
|
|
public class JsonNotificationHTTPServer implements Runnable {
|
|
|
|
// keepRunning
|
|
static boolean keepRunning = true; // nous permettra de signaliser au serveur que c'est sa dernière itération d'écoute
|
|
static String messageToJson = ""; // message qui sera communiqué en JSON à travers HTTP
|
|
|
|
// mode verbose - pour debug
|
|
static final boolean verbose = true;
|
|
|
|
// Connexion client via la classe de Socket
|
|
private Socket connect;
|
|
|
|
public JsonNotificationHTTPServer(Socket c) {
|
|
connect = c;
|
|
}
|
|
|
|
public static void startNotificationServer(int PORT) {
|
|
|
|
RobotIndex robotIndex = new RobotIndex();
|
|
robotIndex.setMessageListener(new MessageListener() {
|
|
@Override
|
|
public void newMessage(String message) {
|
|
messageToJson = message;
|
|
System.out.println("De HTTPServer - message reçu du robot : " + message);
|
|
if (message.contains("\"message\":\"finish\"")) {
|
|
System.out.println("Dernière iteration d'écoute - envoyer une req HTTP pour terminer le thread");
|
|
keepRunning = false;
|
|
}
|
|
}
|
|
});
|
|
|
|
try {
|
|
ServerSocket serverConnect = new ServerSocket(PORT);
|
|
System.out.println("Server lancé.\nEn ecoute sur le port : " + PORT + " ...\n");
|
|
|
|
// On écoute jusqu'à ce que la demande de fermetture soit envoyée
|
|
while (keepRunning) {
|
|
JsonNotificationHTTPServer myServer = new JsonNotificationHTTPServer(serverConnect.accept());
|
|
|
|
if (verbose) {
|
|
System.out.println("Connexion ouverte. (" + new Date() + ")");
|
|
}
|
|
|
|
// Creation d'un thread dedié pour les connexions client
|
|
Thread thread = new Thread(myServer);
|
|
thread.start();
|
|
}
|
|
|
|
} catch (IOException e) {
|
|
System.err.println("Erreur connexion server : " + e.getMessage());
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void run() {
|
|
|
|
// nous gérons notre connexion client
|
|
BufferedReader in = null;
|
|
PrintWriter out = null;
|
|
BufferedOutputStream dataOut = null;
|
|
String fileRequested = null;
|
|
|
|
try {
|
|
// nous lisons les caractères du client via le flux d'entrée sur le socket
|
|
in = new BufferedReader(new InputStreamReader(connect.getInputStream()));
|
|
// nous obtenons le flux de sortie des caractères vers le client (pour les en-têtes)
|
|
out = new PrintWriter(connect.getOutputStream());
|
|
// obtenir le flux de sortie binaire vers le client (pour les données demandées)
|
|
dataOut = new BufferedOutputStream(connect.getOutputStream());
|
|
|
|
// obtenir la première ligne de la request client
|
|
String input = in.readLine();
|
|
// on parse la requête HTTP avec un StringTokenizer
|
|
StringTokenizer parse = new StringTokenizer(input);
|
|
String method = parse.nextToken().toUpperCase(); // on obtient la méthode HTTP du client (GET, POST ..)
|
|
// on obtient la requete - fichier demandé
|
|
fileRequested = parse.nextToken().toLowerCase();
|
|
|
|
// on ne prend en charge que les méthodes GET et HEAD, vérification
|
|
if (!method.equals("GET") && !method.equals("HEAD")) {
|
|
if (verbose) {
|
|
System.out.println("501 Not Implemented : " + method + " method.");
|
|
}
|
|
|
|
// fichier non pris en charge - on renvoie une erreur 501
|
|
String file = "{\"message\":\"501\"}";
|
|
int fileLength = (int) file.length();
|
|
String contentMimeType = "application/json";
|
|
//lecture des données à retourner au client
|
|
byte[] fileData = file.getBytes();
|
|
|
|
// on envoie le HTTP header avec données au client
|
|
out.println("HTTP/1.1 501 Not Implemented");
|
|
out.println("Server: Java HTTP Server from robot : 1.0");
|
|
out.println("Date: " + new Date());
|
|
out.println("Content-type: " + contentMimeType);
|
|
out.println("Content-length: " + fileLength);
|
|
out.println(); // ligne d'espace entre le header et le contenu, très important
|
|
out.flush(); // vidage du tampon de flux de sortie des caractères
|
|
// file
|
|
dataOut.write(fileData, 0, fileLength);
|
|
dataOut.flush();
|
|
|
|
} else {
|
|
// GET or HEAD method
|
|
|
|
String file = messageToJson;
|
|
int fileLength = (int) file.length();
|
|
String content = "application/json";
|
|
|
|
if (method.equals("GET")) { // GET method on envoie le contenu
|
|
byte[] fileData = file.getBytes();
|
|
|
|
// send HTTP Headers
|
|
out.println("HTTP/1.1 200 OK");
|
|
out.println("Server: Java HTTP Server from robot : 1.0");
|
|
out.println("Date: " + new Date());
|
|
out.println("Content-type: " + content);
|
|
out.println("Content-length: " + fileLength);
|
|
out.println(); // ligne d'espace entre le header et le contenu, très important
|
|
out.flush(); // vidage du tampon de flux de sortie des caractères
|
|
|
|
dataOut.write(fileData, 0, fileLength);
|
|
dataOut.flush();
|
|
}
|
|
|
|
if (verbose) {
|
|
System.out.println("File " + fileRequested + " of type " + content + " returned");
|
|
}
|
|
|
|
}
|
|
|
|
} catch (FileNotFoundException fnfe) {
|
|
try {
|
|
fileNotFound(out, dataOut, fileRequested);
|
|
} catch (IOException ioe) {
|
|
System.err.println("Error with file not found exception : " + ioe.getMessage());
|
|
}
|
|
|
|
} catch (IOException ioe) {
|
|
System.err.println("Server error : " + ioe);
|
|
} finally {
|
|
try {
|
|
in.close();
|
|
out.close();
|
|
dataOut.close();
|
|
connect.close(); // Fermeture de la connexion socket avec le client
|
|
} catch (Exception e) {
|
|
System.err.println("Error closing stream : " + e.getMessage());
|
|
}
|
|
|
|
if (verbose) {
|
|
System.out.println("Connection closed.\n");
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
private void fileNotFound(PrintWriter out, OutputStream dataOut, String fileRequested) throws IOException {
|
|
|
|
// En renvoie une erreur 404 au client
|
|
String file = "{\"message\":\"404\"}";
|
|
int fileLength = (int) file.length();
|
|
String content = "application/json";
|
|
//lecture des données à retourner au client
|
|
byte[] fileData = file.getBytes();
|
|
|
|
out.println("HTTP/1.1 404 File Not Found");
|
|
out.println("Server: Java HTTP Server from robot : 1.0");
|
|
out.println("Date: " + new Date());
|
|
out.println("Content-type: " + content);
|
|
out.println("Content-length: " + fileLength);
|
|
out.println(); // ligne d'espace entre le header et le contenu, très important
|
|
out.flush(); // vidage du tampon de flux de sortie des caractères
|
|
|
|
dataOut.write(fileData, 0, fileLength);
|
|
dataOut.flush();
|
|
|
|
if (verbose) {
|
|
System.out.println("File " + fileRequested + " not found");
|
|
}
|
|
}
|
|
|
|
}
|
|
|