我是靠谱客的博主 爱笑悟空,这篇文章主要介绍springboot整合socket实现服务端心跳检测,现在分享给大家,希望可以做个参考。

springboot整合socket实现服务端心跳检测

心跳包 KeepAlive

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import java.io.Serializable; import java.text.SimpleDateFormat; import java.util.Date; /** * * 维持连接的消息对象(心跳对象) */ public class KeepAlive implements Serializable { private static final long serialVersionUID = -2813120366138988480L; /* * 覆盖该方法,仅用于测试使用。 * * @see java.lang.Object#toString() */ @Override public String toString() { return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + "t维持连接包"; } }

服务端 Server

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
import java.io.IOException; import java.io.InputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.net.ServerSocket; import java.net.Socket; import java.util.concurrent.ConcurrentHashMap; import org.springframework.stereotype.Component; @Component public class Server { /** * 要处理客户端发来的对象,并返回一个对象,可实现该接口。 */ public interface ObjectAction{ Object doAction(Object rev, Server server); } public static final class DefaultObjectAction implements ObjectAction{ public Object doAction(Object rev,Server server) { System.out.println("处理并返回:"+rev); return rev; } } private volatile boolean running=false; private long receiveTimeDelay=3000; private ConcurrentHashMap<Class, ObjectAction> actionMapping = new ConcurrentHashMap<Class,ObjectAction>(); private Thread connWatchDog; public void start(){ if(running)return; running=true; connWatchDog = new Thread(new ConnWatchDog()); connWatchDog.start(); } @SuppressWarnings("deprecation") public void stop(){ if(running)running=false; if(connWatchDog!=null)connWatchDog.stop(); } public void addActionMap(Class<Object> cls,ObjectAction action){ actionMapping.put(cls, action); } class ConnWatchDog implements Runnable{ public void run(){ try { ServerSocket ss = new ServerSocket(8092,5); while(running){ Socket s = ss.accept(); new Thread(new SocketAction(s)).start(); } } catch (IOException e) { e.printStackTrace(); Server.this.stop(); } } } class SocketAction implements Runnable{ Socket s; boolean run=true; long lastReceiveTime = System.currentTimeMillis(); public SocketAction(Socket s) { this.s = s; } public void run() { while(running && run){ if(System.currentTimeMillis()-lastReceiveTime>receiveTimeDelay){ overThis(); }else{ try { InputStream in = s.getInputStream(); if(in.available()>0){ ObjectInputStream ois = new ObjectInputStream(in); Object obj = ois.readObject(); lastReceiveTime = System.currentTimeMillis(); System.out.println("接收:t"+obj); ObjectAction oa = actionMapping.get(obj.getClass()); oa = oa==null?new DefaultObjectAction():oa; Object out = oa.doAction(obj,Server.this); if(out!=null){ ObjectOutputStream oos = new ObjectOutputStream(s.getOutputStream()); oos.writeObject(out); oos.flush(); } }else{ Thread.sleep(10); } } catch (Exception e) { e.printStackTrace(); overThis(); } } } } private void overThis() { if(run)run=false; if(s!=null){ try { s.close(); } catch (IOException e) { e.printStackTrace(); } } System.out.println("关闭:"+s.getRemoteSocketAddress()); } } }

springboot启动程序 AdminApplication

复制代码
1
2
3
4
5
6
7
8
9
10
11
@SpringBootApplication public class AdminApplication { public static void main(String[] args) { ConfigurableApplicationContext context = SpringApplication.run(AdminApplication.class, args); context.getBean(Server.class).start(); } }

PC端客户端是C++写的,还是要写一个测试的客户端进行心跳测试

测试客户端 Client

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
import java.io.IOException; import java.io.InputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.net.Socket; import java.net.UnknownHostException; import java.util.concurrent.ConcurrentHashMap; public class Client { /** * 处理服务端发回的对象,可实现该接口。 */ public static interface ObjectAction{ void doAction(Object obj,Client client); } public static final class DefaultObjectAction implements ObjectAction{ public void doAction(Object obj,Client client) { System.out.println("处理:t"+obj.toString()); } } public static void main(String[] args) throws UnknownHostException, IOException { String serverIp = "127.0.0.1"; int port = 8092; Client client = new Client(serverIp,port); client.start(); } private String serverIp; private int port; private Socket socket; private boolean running=false; //连接状态 private long lastSendTime; //最后一次发送数据的时间 //用于保存接收消息对象类型及该类型消息处理的对象 private ConcurrentHashMap<Class, ObjectAction> actionMapping = new ConcurrentHashMap<Class,ObjectAction>(); public Client(String serverIp, int port) { this.serverIp=serverIp; this.port=port; } public void start() throws UnknownHostException, IOException { if(running)return; socket = new Socket(serverIp,port); System.out.println("本地端口:"+socket.getLocalPort()); lastSendTime=System.currentTimeMillis(); running=true; new Thread(new KeepAliveWatchDog()).start(); //保持长连接的线程,每隔2秒项服务器发一个一个保持连接的心跳消息 new Thread(new ReceiveWatchDog()).start(); //接受消息的线程,处理消息 } public void stop(){ if(running)running=false; } /** * 添加接收对象的处理对象。 * @param cls 待处理的对象,其所属的类。 * @param action 处理过程对象。 */ public void addActionMap(Class<Object> cls,ObjectAction action){ actionMapping.put(cls, action); } public void sendObject(Object obj) throws IOException { ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream()); oos.writeObject(obj); System.out.println("发送:t"+obj); oos.flush(); } class KeepAliveWatchDog implements Runnable{ long checkDelay = 10; long keepAliveDelay = 2000; public void run() { while(running){ if(System.currentTimeMillis()-lastSendTime>keepAliveDelay){ try { Client.this.sendObject(new KeepAlive()); } catch (IOException e) { e.printStackTrace(); Client.this.stop(); } lastSendTime = System.currentTimeMillis(); }else{ try { Thread.sleep(checkDelay); } catch (InterruptedException e) { e.printStackTrace(); Client.this.stop(); } } } } } class ReceiveWatchDog implements Runnable{ public void run() { while(running){ try { InputStream in = socket.getInputStream(); if(in.available()>0){ ObjectInputStream ois = new ObjectInputStream(in); Object obj = ois.readObject(); System.out.println("接收:t"+obj); ObjectAction oa = actionMapping.get(obj.getClass()); oa = oa==null?new DefaultObjectAction():oa; oa.doAction(obj, Client.this); }else{ Thread.sleep(10); } } catch (Exception e) { e.printStackTrace(); Client.this.stop(); } } } } }

测试结果也贴一下
在这里插入图片描述
参考文章:
https://blog.csdn.net/weixin_38413579/article/details/86645525
https://blog.csdn.net/zmx729618/article/details/54378259
没错就是把这两篇文章整合了一下。

最后

以上就是爱笑悟空最近收集整理的关于springboot整合socket实现服务端心跳检测的全部内容,更多相关springboot整合socket实现服务端心跳检测内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(69)

评论列表共有 0 条评论

立即
投稿
返回
顶部