我需要在我的Java项目上实现心跳系统(3-5个客户端,其中有1个服务器),但是我有一些疑问。

1)我需要由客户提供2个 socket 吗? 1表示心跳,1表示我的软件收到正常消息

2)我看到在特定情况下,当客户落后时,客户不会收到消息,如何避免这种情况?

3)如果客户端断开连接,如何恢复与之的连接?不用重新创建一个新的套接字。

最佳答案

因此,您有一个“中央服务器”,需要为客户端提供心跳​​机制。嗯,部分解决方案很简单,因为您只有一台服务器,因为不需要处理数据复制,数据同步机制,服务器故障等,因此简化了很多。您只希望服务器永不失败,如果失败,则是致命错误。

我的建议是实现一个基于通知的系统(池化很糟而且很丑陋):与其让服务器池化客户端,不如让客户端每隔X秒向其服务器报告一次。这基于“Tell, don't ask”的设计原理,减少了系统的总体过载。这也使您可以为每个客户拥有不同的报告时间。

还有一个问题,您要传输哪些数据?仅仅是客户是否还活着?客户端的运行时数据,例如,如果客户端正在下载文件,则完成了%的工作?环境状态,例如CPU过载,内存使用情况,网络状态?定义那是第一步。

谈到Java实现,您应该在每个客户端上运行一个线程(实现Runnable接口(interface))。它看起来应该类似于以下代码(为简洁起见,将其简化):

public class HeartbeatAgent implements Runnable {

private int DEFAULT_SAMPLING_PERIOD = 5; //seconds
private String DEFAULT_NAME = "HeartbeatAgent";
private HashMap<Integer, Object> values; // <id, value>


public HeartbeatAgent () {
  values = new HashMap<Integer,Object>();

}


private void collect() {
    /** Here you should collect the data you want to send
        and store it in the hash
    **/

}

public void sendData(){
    /** Here you should send the data to the server. Use REST/SOAP/multicast messages, whatever you want/need/are forced to **/
}

public void run() {
  System.out.println("Running " +  DEFAULT_NAME );
  try {
     while( /** condition you want to stop **/ {
        System.out.println("Thread: " + DEFAULT_NAME + ", " + "I'm alive");

        this.collect();
        this.send();
        // Let the thread sleep for a while.
        Thread.sleep(DEFAULT_SAMPLING_PERIOD * 1000);
     }
 } catch (InterruptedException e) {
     System.out.println("Thread " +  DEFAULT_NAME + " interrupted.");
 }
 System.out.println("Thread " +  DEFAULT_NAME + " exiting.");
}
}

您应该编写一个处理请求的服务器,它“足够聪明”,足以在X秒后调用超时,而没有来自客户端Y的“新闻”。

这仍然不是理想的,因为您收集数据并在相同的采样周期内发送数据,但是通常您希望以很小的间隔(例如,每5秒收集一次CPU使用率)收集数据,而仅每30秒报告一次。

如果要查看执行此操作的良好库的良好代码(这是我们在我公司的项目中一直在使用的代码),请查看JCatascopia框架代码(仅查看Agent和Server文件夹,请忽略其他)。

关于这个话题,有很多要说的,这是基础。随便问!

关于Java心跳设计,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/33869092/

10-11 02:42