简体   繁体   中英

Java and PHP socket communication and AJAX

I have a Java application that is checking if there are changes in the file system - creating, deleting and modifying files and folders. It's sending a message to a PHP application. So here is the case the Java app is running and I'm creating a new file in the specified directory. Java is catching this and displaying it on the console (for testing purpose) and then it's sending it to PHP. When I refresh, I'm seeing the message, however if I don't refresh the page and create a new file in the specified directory Java is not displaying the message neither in the console neither sending it to PHP. So it seems that basically after every change in the folder I have to refresh to catch the changes. I was wondering if I can use AJAX to avoid the refresh after each change. If AJAX is not an option or it won't be working is there another way to do this? Here is my code:

Main

package com.company;

import java.io.IOException;
import java.nio.file.*;

import static java.nio.file.StandardWatchEventKinds.ENTRY_CREATE;
import static java.nio.file.StandardWatchEventKinds.ENTRY_DELETE;
import static java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY;

public class Main {

    public static final String DIRECTORY_TO_WATCH = "D:/Test";

    public static void main(String[] args) throws IOException, InterruptedException {
    // write your code here
        Path toWatch = Paths.get(DIRECTORY_TO_WATCH);
        CommunicationServer server = CommunicationServer.getInstance();
        if(toWatch == null) {
            throw new UnsupportedOperationException("Directory not found");
        }

        // make a new watch service that we can register interest in
        // directories and files with.
        WatchService myWatcher = toWatch.getFileSystem().newWatchService();
       // CommunicationServer server = new CommunicationServer();

        // start the file watcher thread below
        MyWatchQueueReader fileWatcher = new MyWatchQueueReader(myWatcher, server);
        Thread th = new Thread(fileWatcher, "FileWatcher");
        th.start();

        // register a file
        toWatch.register(myWatcher, ENTRY_CREATE, ENTRY_MODIFY);
        th.join();
    }
}

Reader

package com.company;

import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;

/**
 * Created by Ivan on 3/16/2016.
 */
public class MyWatchQueueReader implements Runnable {

    /** the watchService that is passed in from above */
    private WatchService myWatcher;
   private CommunicationServer server;
    public MyWatchQueueReader(WatchService myWatcher, CommunicationServer server) {
        this.myWatcher = myWatcher;
        this.server = server;
    }

    /**
     * In order to implement a file watcher, we loop forever
     * ensuring requesting to take the next item from the file
     * watchers queue.
     */
    @Override
    public void run() {
        try {
            // get the first event before looping
            WatchKey key = myWatcher.take();
            while(key != null) {
                // we have a polled event, now we traverse it and
                // receive all the states from it
                for (WatchEvent event : key.pollEvents()) {
                    System.out.printf("Received %s event for file: %s\n",
                            event.kind(), event.context() );
                    System.out.printf("Received\n");
                    String line = "Received " + event.kind() + " event for file: " + event.context() + "\n";
                    server.StartCommunicationg(line + "\n");
                    System.out.printf(" Not Received\n");
                }
                key.reset();
                key = myWatcher.take();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("Stopping thread");
    }
}

Server:

package com.company;

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * Created by Ivan on 3/16/2016.
 */
public class CommunicationServer {
    private static int port = 20222;
    private static ServerSocket listenSock = null;
    private Socket sock = null;
    private static CommunicationServer instance = null;

    protected CommunicationServer() {
        System.out.println("Communication has started");
    }

    public static CommunicationServer getInstance() {
        if (instance == null) {
            instance = new CommunicationServer();
            try{
                listenSock = new ServerSocket(port);
            } catch (IOException ex){
                ex.printStackTrace();
            }
        }

        return instance;
    }

    public void StartCommunicationg(String message) {
        try {



            //while(true) {
                this.sock = listenSock.accept();

                BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(sock.getOutputStream()));

                writer.write(message + "/n");
                writer.flush();
                writer.close();
                sock.close();
            //}
        } catch (IOException ex) {
            ex.printStackTrace();
        }


    }
}

PHP

<?php

$PORT = 20222; //the port on which we are connecting to the "remote" machine
$HOST = "localhost"; //the ip of the remote machine (in this case it's the same machine)

$sock = socket_create(AF_INET, SOCK_STREAM, 0) //Creating a TCP socket
        or die("error: could not create socket\n");

$succ = socket_connect($sock, $HOST, $PORT) //Connecting to to server using that socket
        or die("error: could not connect to host\n");

//$text = "Hello, Java!"; //the text we want to send to the server

//socket_write($sock, $text . "\n", strlen($text) + 1) //Writing the text to the socket
        //or die("error: failed to write to socket\n");

$reply = socket_read($sock, 10000, PHP_NORMAL_READ) //Reading the reply from socket
        or die("error: failed to read from socket\n");

echo $reply;
?>

The whole idea is that I have a folder let's say D:\\Test. Not sure if there is away to show the user if there were changes in this - creating a folder or file using only PHP. So I decided to use Java to be looking for changes in the file system. When there is a change, the user should see let's say a notification in the browser.If the PHP application is not running the Java app should be checking for changes in this folder and when the PHP app is running again, it should receive all the changes that were done in the folder.. With so many issues with the communication between both apps I'm wondering if it won't be even better to use database? But then comes the question, how the PHP will know that the DB was updated... Getting really confused here...

Any help here will be greatly appreciated.

Regards, Ivan

essentially I don't agree with you CommunicationServer Java Class, It's better to use Java Servlet, instead of using socket and PHP.

Any way if you want to use this strategy I have to say that the loaded web page on the browser will be not refreshed automatically and it needs that you press refresh key or you add a AJAX code which can be loaded after a while. for example you can use a code like this

setInterval(function(){
  // your code
}, 10000);

for more information in this scope i would highly recommend to check out this link

Attempting to understand your problem, I think you might need an extra process. AJAX could help, but it doesn't solve the problem of the fact that the PHP needs to keep spinning.

You could just use AJAX to keep polling the PHP instance, but I think it will miss any file change events that happen may happen in between the polling time, as they do not appear to be caught by the PHP session.

One solution is WebSockets, that allow you to communicate data on an event basis to the user, so with this, you can have one TCP socket to your Java application, and one WebSocket to the end-user, which will send through any information regarding file changes when they happen, however support is limited and this may be difficult.

Alternatively, you could have one process on the PHP server running in the background, submitting this information to a database of some variety (since it's running on the same server, the Java applet could be doing this instead, depending on your scenario) and then just timestamp the entries, and have AJAX poll the PHP session. This way, nothing will be missed or dropped no matter what the polling time is, and you can delete the entries once they've been forwarded if they're no longer relevant.

Either way, this can be tricky to solve with a web browser, as you're trying to notify the client of new information. If you're feeling lazy, you can just have PHP never close the session, and continue to echo data to the browser.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM