由于最近要做一个客户端,但是要求有一个掉线检测的功能,下面让我们看看使用自定义的HeartBeat方式来检测客户端的连接情况。
心跳包的实现思路:
客户端连接上服务端后,在服务端会维护一个在线客户端列表。客户端每隔一段时间,向服务端发送一个心跳包,服务端受收到包以后,会更新客户端最近一次在线时间。一旦服务端超过规定时间没有接收到客户端发来的包,则视为掉线。
代码:
客户端每隔一段时间,发送一个心跳包:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
var timer = new System.Timers.Timer(); timer.Interval = 60000; //1m触发一次 timer.Start(); timer.Elapsed += (sender, args) => { Console.WriteLine( "开始发送心跳包" ); MMessage message = new MMessage(); message.MessageType = MessagePicks.Heartbeat; // message.From = loginName; WriteToStream(message); }; |
服务端每隔一段时间检测:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
var timer = new Timer(); timer.Interval = 60000; //1m触发一次 timer.Start(); timer.Elapsed += (sender, args) => { List<MClient> offClients = new List<MClient>(); foreach ( var client in clients) { if ((DateTime.Now - client.LastOnLine).TotalMinutes > 1) { Console.WriteLine( "用户" + client.Name + "掉线!" ); offClients.Add(client); } } foreach ( var offClient in offClients) { clients.Remove(offClient); } }; |
服务端收到心跳包的处理逻辑:
1
2
3
4
5
6
7
8
9
10
|
Console.WriteLine( "收到客户端" + msg.RemoteEndPoint + "的心跳回应包." ); client.LastOnLine = DateTime.Now; //收到心跳包,更新时间 client.Name = msg.RemoteEndPoint.ToString(); client.RemoteEndPoint = msg.RemoteEndPoint; if (!clients.Contains(client)) { clients.Add(client); } |
效果: