简体   繁体   English

Java和PHP套接字通信和AJAX

[英]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. 我有一个Java应用程序正在检查文件系统中是否有更改-创建,删除和修改文件和文件夹。 It's sending a message to a PHP application. 它正在向PHP应用程序发送消息。 So here is the case the Java app is running and I'm creating a new file in the specified directory. 因此,这是Java应用程序正在运行的情况,我正在指定目录中创建一个新文件。 Java is catching this and displaying it on the console (for testing purpose) and then it's sending it to PHP. Java正在捕获该错误并将其显示在控制台上(用于测试目的),然后将其发送到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. 刷新时,我会看到消息,但是,如果不刷新页面并在指定目录中创建新文件,则Java既不会在控制台中也不显示消息,也不会将其发送给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. 我想知道是否可以使用AJAX来避免每次更改后的刷新。 If AJAX is not an option or it won't be working is there another way to do this? 如果AJAX不是一个选项,或者它无法正常工作,还有另一种方法吗? 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

<?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. 整个想法是我有一个文件夹,例如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. 不知道是否可以向用户显示其中是否有更改-仅使用PHP创建文件夹或文件。 So I decided to use Java to be looking for changes in the file system. 因此,我决定使用Java查找文件系统中的更改。 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? 发生更改时,用户应在浏览器中看到一条通知。如果PHP应用程序未运行,则Java应用程序应检查此文件夹中的更改,而当PHP应用程序再次运行时,它应收到所有文件夹中所做的更改。两个应用程序之间的通信存在很多问题,我想知道使用数据库是否会更好? But then comes the question, how the PHP will know that the DB was updated... Getting really confused here... 但是随之而来的问题是,PHP将如何知道数据库已更新...在这里变得非常困惑...

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. 本质上,我不同意CommunicationServer Java类,最好使用Java Servlet,而不要使用套接字和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. 无论如何,如果要使用此策略,我不得不说,浏览器中加载的网页将不会自动刷新,并且需要按刷新键或添加AJAX代码,稍后可以加载。 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. AJAX可以提供帮助,但不能解决PHP需要持续旋转的问题。

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. 您可以只使用AJAX来继续轮询PHP实例,但是我认为它将错过在轮询时间之间可能发生的任何文件更改事件,因为它们似乎没有被PHP会话捕获。

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. 一种解决方案是WebSockets,它允许您根据事件将数据传递给用户,因此,您可以拥有一个Java应用程序的TCP套接字和一个最终用户的WebSocket,这将通过任何有关以下信息的发送文件发生更改时,但是支持有限,这可能很困难。

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. 或者,您可以在后台运行的PHP服务器上有一个进程,将该信息提交到各种数据库中(由于它在同一服务器上运行,因此Java applet可以根据您的情况执行此操作),然后只需给条目加上时间戳,并让AJAX轮询PHP会话。 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. 无论哪种方式,在尝试将新信息通知客户端时,使用Web浏览器都很难解决。 If you're feeling lazy, you can just have PHP never close the session, and continue to echo data to the browser. 如果您感到懒惰,则可以让PHP从不关闭会话,并继续将数据回显到浏览器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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