目录
归档
5783
2018 年 02 月 06 日
ET框架心跳包组件开发(362946写)

网络游戏经常会发生(玩家断网、电脑死机、等)现象、这些会造成服务器里存在很多Session存在。

为什么Session会一直存在,不会自动销毁吗?因为服务器是不会知道这个Session是不是(玩家断网、电脑死机、等)现象。

断开网络连接需要4次握手才可以完成、但(玩家断网、电脑死机、等)现象是不会有4次握手的。

明白了这个问题,就需要做一个功能那就是每隔一段时间给服务器发送数据,表示我还在跟你连接,如果服务器里发现某个Session长时间没有发包了那就表示这个Session是无效的。

ET很强大,但没有提供这个心跳,需要自己开发一个这样的功能。

设计思路:

  • 心跳协议包(进行客户端跟服务端相互通信的数据包)
  • 心跳组件(ET是ECS框架也就是组件式、所以要开发出客户端和服务端的组件)

心跳协议包(服务端和客户端都需要):

需要在Opcode.cs里添加两个枚举、分别C2R_HeartBeat、R2C_HeartBeat

public enum Opcode: ushort

{

C2R_HeartBeat = 500,

R2C_HeartBeat = 501

}

需要在OuterMessage.cs文件里的添加两个类、分别C2R_HeartBeat、R2C_HeartBeat

QQ图片20180206170908

需要在OuterMessage.cs文件里的public partial class  ARequest {}上添加

ProtoInclude((int)Opcode.C2R_HeartBeat, typeof(C2R_HeartBeat))]

[BsonKnownTypes(typeof(C2R_HeartBeat))]

需要在OuterMessage.cs文件里的public partial class  AResponse {}上添加

[ProtoInclude((int)Opcode.R2C_HeartBeat, typeof(R2C_HeartBeat))]
[BsonKnownTypes(typeof(R2C_HeartBeat))]

2

服务端心跳组件:

Model项目下Component文件夹下创建HeartBeatComponent.cs文件并使用以下代码

[ObjectSystem]

public class HeartBeatSystem : ObjectSystem<HeartBeatComponent>, IUpdate

{

public void Update()

{

this.Get().Update();

}

}

/// <summary>

/// Session心跳组件(需要挂载到Session上)

/// </summary>

 

public class HeartBeatComponent : Component

{

/// <summary>

/// 更新间隔

/// </summary>

public long UpdateInterval = 5;

/// <summary>

/// 超出时间

/// </summary>

/// <remarks>如果跟客户端连接时间间隔大于在服务器上删除该Session</remarks>

public long OutInterval = 10;

/// <summary>

/// 记录时间 ///

</summary>

private long _recordDeltaTime = 0;

/// <summary>

/// 当前Session连接时间

/// </summary>

public long CurrentTime = 0; public void Update()

{

// 如果没有到达发包时间、直接返回

if (!((TimeHelper.ClientNowSeconds() – this._recordDeltaTime) > this.UpdateInterval) || CurrentTime == 0) return;

// 记录当前时间

this._recordDeltaTime = TimeHelper.ClientNowSeconds();

if ((TimeHelper.ClientNowSeconds() – CurrentTime) > OutInterval)

{

// 移除Session

Game.Scene.GetComponent<NetOuterComponent>().Remove(this.Parent.Id);

Game.Scene.GetComponent<NetInnerComponent>().Remove(this.Parent.Id);

Game.Scene.GetComponent<GateSessionKeyComponent>().Remove(this.Parent.Id);

}

}

}

这段代码实现的功能是每隔一段时间检查当前Session连接时间是否超过OutInterval设定的时间,如果超过那就表示客户端可能是断线了。

那就需要把这个Session给销毁掉。

服务端挂载心跳组件:

需要挂载到网关服务器上。

添加心跳组件:session.AddComponent<HeartBeatComponent>().CurrentTime = TimeHelper.ClientNowSeconds();

在R2G_GetLoginKeyHandler.cs文件里挂载上心跳组件

3

CurrentTime是当前连接时间,服务端每次接收到客户端的心跳包都会把服务器时间更新到CurrentTime里。

有了CurrentTime的时间就可以判断客户端是否掉线。

Session是每个客户端的连接、我需要把心跳组件挂载到Session上,这样就能实时监测每个Session的状态,如果是断开的就把自己销毁掉。

服务端收发心跳包:

在Hotfix项目Handler文件夹下创建C2R_HeartBeatHandler.cs并使用以下代码

[MessageHandler(AppType.Gate)]
public class C2R_HeartBeatHandler : AMRpcHandler<C2R_HeartBeat, R2C_HeartBeat>
{
protected override void Run(Session session, C2R_HeartBeat message, Action<R2C_HeartBeat> reply)
{
if (session.GetComponent<HeartBeatComponent>() != null)
{
session.GetComponent<HeartBeatComponent>().CurrentTime = TimeHelper.ClientNowSeconds();
}

reply(new R2C_HeartBeat());
}
}

找到Session并更新下HeartBeatComponent的连接时间

客户端心跳组件:

的Component文件夹下创建HeartBeatComponent.cs文件,并使用以下代码

[ObjectSystem]

public class HeartBeatSystem : ObjectSystem<HeartBeatComponent>,IUpdate

{

public void Update()

{

this.Get().Update();

}

}

/// <summary>

/// Session心跳组件(需要挂载到Session上)

/// </summary>

public class HeartBeatComponent: Component

{

/// <summary>

/// 心跳包间隔

/// </summary>

public float SendInterval = 2f;

/// <summary>

/// 记录时间

/// </summary>

private float RecordDeltaTime = 0f;

public async void Update()

{

// 如果还没有建立Session直接返回、或者没有到达发包时间

if (!((Time.time – this.RecordDeltaTime) > this.SendInterval)) return;

// 记录当前时间

this.RecordDeltaTime = Time.time;

// 开始发包

try

{

R2C_HeartBeat result = (R2C_HeartBeat) await this.GetParent<Session>().Call(new C2R_HeartBeat());

}

catch

{

// 执行断线后的操作 Debug.Log(“断线了”);

}

}

}

客户端挂载心跳组件:

Game.Scene.GetComponent<SessionComponent>().Session.AddComponent<HeartBeatComponent>();

这个组件挂载什么位置看个人而定,我是挂载到第一次跟服务器通讯的地方了。

 

全部代码打包在QQ群:474643097里下载

 

转载原创文章请注明,转载自: Tinkingli博客 » ET框架心跳包组件开发(362946写)
留言
Loading...

发表评论

电子邮件地址不会被公开。 必填项已用*标注