天天看点

TCP之心跳包实现思路

说起网络应用编程,想到最多的就是聊天类的软件。当然,在这类软件中,一般都会有一个用户掉线检测功能。今天我们就通过使用自定义的HeartBeat方式来检测用户的掉线情况。

心跳包实现思路

我们采用的思路是:客户端连接上服务端以后,服务端维护一个在线用户字典,客户端每隔一段时间,向服务器发送一个心跳包,服务器接收到包以后,字典 数据的值都会更新为0;一旦服务端超过规定时间没有接收到客户端发来的包,字典数据将会递增加一,当字典数据的值累计大于等于三,则视为掉线。

TCP之心跳包实现思路

代码逻辑

客户端每隔一段时间,发送一个心跳包:

TCP之心跳包实现思路
TCP之心跳包实现思路

 View Code

#region 心跳Timer计数事件

private void heartbeatTimer_Tick(object sender, EventArgs e)

{

currentCount++;

if (currentCount == heartbeatCount)

txtMessage.Append("开始发送心跳包");

MessageEntity entity = new MessageEntity();

entity.MessageType = MessagePicks.Heartbeat;

entity.NickName = loginName;

WriteToStream(entity);

currentCount = 0;

}

#endregion

TCP之心跳包实现思路

在服务端,会开启一个定时器,定时将userOnLineCounter中的值递增加一。如果此时收到客户端的心跳包,则将userOnLineCounter中的值重置。

TCP之心跳包实现思路
TCP之心跳包实现思路

tickCountInStep++;

if (tickCountInStep == tickCount)

if (userCollection.Count > 0)

//计数器自动递增

expiryCountInStep++;

foreach (User user in userLists)

userOnLineCounter[user]++;

//连续监测三次之后,开始监测集合中的掉线情况

if (expiryCountInStep == expiryCount)

//寻找集合中“掉线”的用户

var disconnectedUsers = userOnLineCounter.Where(p => p.Value >= 3).ToList();

foreach (var disconnectedUser in disconnectedUsers)

txtLog.Append("用户" + disconnectedUser.Key.name + "掉线!");

//删除集合中被视为掉线的用户

userLists.Remove(disconnectedUser.Key);

userOnLineCounter.Remove(disconnectedUser.Key);

//开始广播发送掉线用户

entity.MessageType = MessagePicks.OffLine;

EndPoint curOfflineUserEP = disconnectedUser.Key.client.Client.RemoteEndPoint;

string userName = disconnectedUser.Key.name;

entity.MessageContentEx.Add(curOfflineUserEP, userName);

ObjectInversion inversion = new ObjectInversion();

byte[] byteArr = inversion.SerializeTo((object)entity);

try

user.writer.Write(byteArr);

user.writer.Flush();

catch { }

expiryCountInStep = 0;

tickCountInStep = 0;

TCP之心跳包实现思路

收到客户端心跳包,自动重置计数器。

TCP之心跳包实现思路
TCP之心跳包实现思路

case MessagePicks.Heartbeat:

txtLog.Append("收到客户端" + entity.NickName + "的心跳回应包.");

if (userOnLineCounter.ContainsKey(user))

userOnLineCounter[user] = 0;

else

userOnLineCounter.Add(user, 0);

break;

TCP之心跳包实现思路

效果图

TCP之心跳包实现思路

(图1:三个客户端连接一个服务器)

TCP之心跳包实现思路

(图2:用户“上善若水”掉线)

TCP之心跳包实现思路

(图3:用户“古道热肠”掉线)

 程序暂时还未完全完成,有需要的可以参考下。当然也期待大家的各种思路。

代码很丑,期望大家指点下重构的方法。

源码下载

<a href="http://files.cnblogs.com/scy251147/ChattingSolution%2820130922%29.rar">点击这里下载</a>

    

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

版权信息

继续阅读