2016-05-14 15 views
0

非常に簡単なインターフェイスで劇場のライトを制御するためにJavaFXで書かれたアプリケーションがあります。基本的に2つのボタン、1つはフェードインして3秒間点灯し、もう1つは3秒間フェードアウトします。このアプリケーションは、イーサネットからシリアルサーバー(Sealevel Sealink 4104)に接続してライトを制御します。埋め込みJava Webサーバーは、アプリケーションインターフェイスを非表示にします

ブラウザのインターフェイスを追加して、モバイルデバイスからアプリを制御できるようにしたいと考えています。私はこのビデオから得たコードに基づいてJava Webサーバーを追加しました。

https://www.youtube.com/watch?v=G4Z2PQfOHdY

アプリが実行され、私は、ブラウザで探していますWebページを取得することができます。しかし、私のアプリケーションのインターフェイスが表示されることはありません。アイデアは、アプリケーションインターフェイスが常に実行中であることを示すために存在することです。ウェブページインターフェースは、制御オプションをモバイルデバイスに拡張するために利用可能である。

この時点での主な質問は、アプリケーションインターフェイスの機能に干渉することなく、Webサーバーをバックグラウンドで実行させる方法です。

Webサーバコード:

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); 
    } 
} 
} 

ここでは、インタフェースコードです:

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); 

} 

} 
+0

:-)あなたのショーをいじり始めるのだろうか? JNLPが考えられますが、それはアプリケーション全体がサーバーからクライアントに転送されることを意味します。この場合、モバイルは良いアプローチとして私を攻撃しません。 – hotzst

+0

ユーザーはブラウザを開き、アプリケーションを実行しているコンピュータのIPアドレスを入力します。例として、192.168.1.16:9000/www/light control.html。 – CelestialCoyote

答えて

0

私はJavaFXのは、そのスレッドのバックが必要であることを推測するつもりです。 start()が呼び出され、webserver.StartServer()が呼び出されます。これは、無限のwhile(true)ループのままです。 socket acceptingループを別のスレッドで実行し(必要に応じて適切にシャットダウンして)、startメソッドを返すようにしてください。

擬似HTTPサーバーを自分で実装することはお勧めできません。これは単なるコード、作業、保守の追加であり、RFC準拠でない場合はさまざまな方法で中断する可能性があります。あなたが使用できる埋め込み可能な軽量HTTPサーバーはたくさんあります。 JLHTTPの著者として、あなたのユースケースには良い一致があると思いますが、他にも多くの選択肢があります。ノート

public void startWebServer() { 
    String dir = "."; // local folder to serve website files from 
    HTTPServer server = new HTTPServer(9000); // pick a port, any port 
    HTTPServer.VirtualHost host = server.getVirtualHost(null); // default virtual host 
    host.addContext("/", new FileContextHandler(new File(dir), "/")); // serve website files from disk directory 
    host.addContext("/api/lights", (request, response) -> { 
     Map<String, String> params = request.getParams(); 
     String action = params.get("action"); 
     if (action == null) 
      action = ""; 
     switch (action) { 
      case "on": 
       connect.sendCommand("3N:100:A"); 
       return 200; // ok 
      case "off": 
       connect.sendCommand("3F:A"); 
       return 200; // ok 
      default: 
       return 400; // bad request 
     } 
    }, "GET", "POST"); // support both GET and POST requests 
    server.start(); 
} 

: -

  • ウェブサイトのファイル(HTML/JS/CSS/imagsなど)は、ディスクから提供されているJLHTTP 2.1を使用して

    、あなたはこのようなものが必要だろうこの例ではカレントディレクトリを使用していますが、それを専用ディレクトリに変更して、機密ファイルへの意図しないアクセスを防ぐ必要があります。

  • クライアントコードでは、適切なアクションパラメータと値を送信する限り、POSTまたはGETリクエスト、フォーム、AJAX、クエリパラメータ付きURLなどを使用できます。
  • アプリケーション、接続、HTTPServerなども正しく閉じてください。
  • この例では、単一のオン/オフアクションパラメータを受け入れます。クライアント側で柔軟性が必要な場合は、個々のコマンド/デバイス/値パラメータを渡して、コンテキストコントローラでライトコントローラのコマンド文字列を作成することができます。
  • あなたが作業すべてを取得した後、あなたにも、セキュリティを考慮しなければならない、または聴衆の中にいくつかの子供は、あなたのアプリケーションは、Webページ上で利用可能にする方法を
+0

私はJLTHTTPサーバーを自分のアプリケーションに追加して動作させました。 – CelestialCoyote

関連する問題