Ich habe eine Anwendung in JavaFX geschrieben, um einige Lichter in einem Theater mit einer sehr einfachen Schnittstelle zu steuern. Im Grunde leuchten zwei Tasten, eine für das Überblenden, über 3 Sekunden und die andere für 3 Sekunden. Die App verbindet sich mit einem Ethernet-zu-Serial-Server (Sealevel Sealink 4104), um die Lichter zu steuern.eingebetteter Java Webserver verbirgt App-Schnittstelle
Ich möchte eine Browser-Schnittstelle hinzufügen, so dass die App über jedes mobile Gerät gesteuert werden kann. Ich habe einen Java-Webserver hinzugefügt, der auf dem Code basiert, den ich aus diesem Video erhalten habe.
https://www.youtube.com/watch?v=G4Z2PQfOHdY
Die App läuft, und ich kann die Web-Seite, die ich für im Browser suchen bekommen. Die Benutzeroberfläche meiner App wird jedoch nie angezeigt. Die Idee ist, dass die App-Schnittstelle immer vorhanden ist, um anzuzeigen, dass sie ausgeführt wird. Die Webseite-Schnittstelle wäre verfügbar, um die Steueroptionen auf ein mobiles Gerät zu erweitern.
Die Hauptfrage an diesem Punkt ist, wie bekomme ich den Webserver im Hintergrund laufen, ohne die Funktionsweise der App-Schnittstelle zu stören?
Der Web-Server-Code:
package lightcontrol2;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.StringTokenizer;
public final class JavaWebserver {
public final void StartServer() throws Exception {
// Set port number.
int port = 9000;
// Establish the listening socket.
ServerSocket serverSocket = new ServerSocket(port);
// Process HTTP sevice requests in an infinite loop.
while (true) {
// Listen for TCP connection request.
Socket connectionSocket = serverSocket.accept();
// Construct an object to process the HTTP request message.
HttpRequest request = new HttpRequest(connectionSocket);
// Create a new thread to process the request.
Thread thread = new Thread(request);
// Start the thread.
thread.start();
}
}
}
final class HttpRequest implements Runnable {
// Return carriage return (CR) and line feed (LF).
final static String CRLF = "\r\n";
Socket socket;
// Constructor.
public HttpRequest(Socket socket) throws Exception {
this.socket = socket;
}
// Implement the run() method of the Runnable interface.
// Within run(), explicitly catch and handle exceptions
// with try/ catch block.
@Override
public void run() {
try {
processRequest();
} catch (Exception e){
System.out.println(e);
}
}
private void processRequest() throws Exception {
// Get a reference to the socket's input and output streams.
InputStream instream = socket.getInputStream();
DataOutputStream os = new DataOutputStream(socket.getOutputStream());
// Set up input stream filters.
// Page 169, 10th line down or so . . .
// Reads the input data.
BufferedReader br = new BufferedReader(new InputStreamReader(instream));
// Get the request line of the HTTP request message.
// Get path/file.html version of http
String requestLine = br.readLine();
// Display the request line.
System.out.println();
System.out.println(requestLine);
// Deal with the request.
// Extract the filename from the request line.
// This is an input method with deliminators.
StringTokenizer tokens = new StringTokenizer(requestLine);
// Skip over the method, which should be 'GET'.
tokens.nextToken();
String fileName = tokens.nextToken();
// Root of the server.
String root = "/www/";
fileName = root + fileName;
// Open the requested file.
FileInputStream fis = null;
boolean fileExists = true;
try {
fis = new FileInputStream(fileName);
} catch (FileNotFoundException e) {
fileExists = false;
}
// Construct the response message.
String statusLine = null;
String contentTypeLine = null;
String entityBody = null;
if (fileExists) {
statusLine = "HTTP/1.0 200 OK" + CRLF;
contentTypeLine = "Content-type: " + contentType(fileName) + CRLF;
}
else {
statusLine = "HTTP/1.0 404 Not Found" + CRLF;
contentTypeLine = "Content-type: " + "text/html" + CRLF;
entityBody = "<HTML>" +
"<HEAD><TITLE>Not Found</TITLE></HEAD>" +
"<BODY>NOt Found</BODY></HTML>";
}
//Send the status line.
os.writeBytes(statusLine);
// Sent the content type line.
os.writeBytes(contentTypeLine);
// Send a blank line to indicate the end of the header lines.
os.writeBytes(CRLF);
// Send the entity body.
if (fileExists) {
sendBytes(fis, os);
os.writeBytes(statusLine);
fis.close();
} else {
os.writeBytes(statusLine);
os.writeBytes(entityBody);
os.writeBytes(contentTypeLine);
}
System.out.println("*****");
System.out.println(fileName);
System.out.println("*****");
// Get and display the header lines.
String headerLine = null;
while ((headerLine = br.readLine()).length() != 0) {
System.out.println(headerLine);
}
// Close streams and socket.
os.close();
br.close();
socket.close();
}
private static String contentType(String fileName) {
if (fileName.endsWith(".htm") || fileName.endsWith(".html")) {
return "text/html";
}
if (fileName.endsWith(".jpg") || fileName.endsWith(".jpeg")) {
return "image/jpeg";
}
if (fileName.endsWith(".gif")) {
return "image/gif";
}
return "application/octet-stream";
}
private static void sendBytes(FileInputStream fis, OutputStream os) throws Exception {
// Construct 1K buffer to hold bytes on way to the socket.
byte[] buffer = new byte[1024];
int bytes = 0;
// Copy requested file into the socket's output stream.
// read() returns -1, indicating end of file.
while ((bytes = fis.read(buffer)) != -1) {
os.write(buffer, 0, bytes);
}
}
}
Hier ist die Interface-Code:
package lightcontrol2;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;
public class LightControl2 extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
GridPane grid = createGrid();
SealinkConnect connect = new SealinkConnect();
JavaWebserver webserver = new JavaWebserver();
Button btnOn = new Button();
grid.add(btnOn, 0, 1);
btnOn.setText("3 Sec On");
btnOn.setOnAction((ActionEvent event) -> {
System.out.println("3N:100:A");
connect.sendCommand("3N:100:A");
});
Button btnOff = new Button();
grid.add(btnOff, 0, 2);
btnOff.setText("3 Sec Off");
btnOff.setOnAction((ActionEvent event) -> {
System.out.println("3F:A");
connect.sendCommand("3F:A");
});
BorderPane root = new BorderPane();
root.setPadding(new Insets(10));
root.setCenter(grid);
Scene scene = new Scene(root, 365, 300);
primaryStage.setTitle("Light Control Test");
primaryStage.setScene(scene);
scene.getStylesheets().add
(LightControl2.class.getResource("style.css").toExternalForm());
primaryStage.show();
connect.socketConnect();
webserver.StartServer();
}
private GridPane createGrid() {
GridPane grid = new GridPane();
grid.setAlignment(Pos.CENTER);
grid.setHgap(5);
grid.setVgap(10);
grid.setPadding(new Insets(10));
return grid;
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
Wie ist Ihre Anwendung auf der Webseite zur Verfügung gestellt? JNLP kommt mir in den Sinn, aber das würde bedeuten, dass die gesamte Anwendung vom Server auf den Client übertragen wird, das mobile in diesem Fall, was mir nicht als guter Ansatz erscheint. – hotzst
Der Benutzer öffnet einen Browser und gibt die IP-Adresse des Computers ein, auf dem die App ausgeführt wird. Als Beispiel 192.168.1.16:9000/www/light control.html. – CelestialCoyote