我需要在我的Java项目中实现一个心跳系统(3-5个客户端,1个服务器),但我有一些问题。
1)客户端是否需要两个套接字?一个用于心跳,一个用于接收软件的正常消息
2)我看到在特定情况下,当客户端延迟时,客户端没有收到消息,如何避免这种情况?
3)当客户端断开连接时,如何恢复连接?而不用它重新创建新的套接字。
发布于 2015-11-23 19:18:28
因此,您有一个“中央服务器”,它需要为客户端提供一种心跳机制。解决方案的一部分很简单,因为您只有一台服务器,这大大简化了您,因为您不需要处理数据复制、数据同步机制、服务器故障等问题。你只是希望你的服务器永远不会出故障,如果它出了故障,那就是一个致命的错误。
我的建议是实现一个基于通知的系统(池化很糟糕):让客户端每X秒向服务器报告一次它们的状态,而不是让服务器将客户端池化一次。这减少了系统的一般过载,并且它基于"Tell, don't ask“的设计原则。这还允许您为每个单独的客户端提供不同的报告时间。
还有一个问题,那就是你想传输什么数据?如果客户端还活着的话?客户端的运行时数据,例如,客户端正在下载文件时完成的作业的百分比?环境状态,例如CPU过载、内存使用、网络状态?定义这一点,这是第一步。
说到java实现,你应该在每个客户机上运行你的线程(实现Runnable接口)。它应该看起来像这样的代码(为了简洁起见,简化了代码):
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框架代码(只需查看代理和服务器文件夹,忽略其他的)。
关于这个话题有很多要说的,这是基本的。请随时提问!
发布于 2018-10-06 04:21:26
你可以试着看看我为一个项目做的这个小框架,我去年参与了一个项目。它专注于一个简单的实现,并提供关于客户状态的强有力的反馈。
它基于UDP协议,它发送一个包含id的有效负载,id可以是NIC的MAC地址,也可以是您自动选择和设置的id或其他东西,以确认客户端是安全的和健康的。
我认为这很酷,因为它基于侦听器,然后侦听器根据心跳协议计算的客户端状态接收各种事件。
你可以在here找到更多关于它的信息
我认为将它与TCP套接字一起使用来了解您是否有能力通过TCP流发送数据是很方便的。拥有对客户状态的连续反馈可以让您轻松实现这一点,例如,通过将客户状态保存在某种地图中,并在发送任何类型的数据之前对其进行检查。
https://stackoverflow.com/questions/33869092
复制相似问题