我设计的脚本功能的游戏服务器。一般的设计是这样的:

Client connects to Server,
Server initializes Client,
Server sends Client to EventManager (separate thread, uses libevent),
EventManager receives receive Event from Client socket,
Client manages what it received via callbacks.

现在最后的部分是什么,现在是最棘手的我。

目前我的设计让我为它继承Client创建回调到特定接收到的事件的类。这些回调在列表管理和接收缓冲区,然后通过解析过程每次接收的东西。如果缓冲区有效,则回调被调用的地方是什么时在缓冲作用。有一点要注意的是,回调可以去到脚本引擎,在这一点没有什么是一定会发生什么。

每个时间回调结束,当前的接收缓冲器必须被重置等回调目前没有返回值的能力,因为如前所述,什么都可能发生。

会发生什么事是,当某个地方回调的东西说,这 - >断开(),我想立即断开Client,从EventManager删除它,最后从Server,它也应该得到最终销毁删除和释放内存。不过,我还是有一些代码运行在回调客户端完成后,因此,我不能释放内存。

我应该在设计变更?我应该在哪些检查其Servers可以自由破坏Client一些定时事件?将创造额外的开销,我不需要?将它仍然是好的回调完成之后运行在堆栈(return -1;)最少的代码或不?

我不知道该怎么做,但我打开完整的设计revamps。

预先感谢。

有帮助吗?

解决方案

可以使用一个参考计数指针等boost::shared_ptr<>简化存储器管理。如果经理的客户名单使用shared_ptrs并调用回调函数的代码创建shared_ptr回调要求的本地副本,直到它从管理者的的回调函数删除的对象将活路完成:

class EventManager {
  std::vector< boost::shared_ptr<Client> > clients;

  void handle_event(Event &event) {
    // local |handler| pointer keeps object alive until end of function, even
    // if it removes itselfe from |clients|
    boost::shared_ptr<Client> handler = ...;
    handler->process(event);
  }
};

class Client {
  void process(Event &event) {
    manager->disconnect(this);
    // the caller still holds a reference, so the object lives on
  }
}

一旦最后Client到它超出范围的shared_ptr对象将被自动删除,而不是之前。因此,创建shared_ptr的本地拷贝函数调用确保对象不意外地删除了。

其他提示

您应该考虑具有像“会话”,其将跟踪从开始到结束特定消息流(从客户端)的对象。 此对象还应该照顾当前状态:主要是缓冲和处理。 每触发一个回调事件必须更新相应会话的状态。 LIBEVENT能够为您提供调度事件的任何结果:成功,失败,超时。此类型的每个人都应该用你的逻辑来体现。 一般情况下,处理事件时,考虑自己的处理逻辑可与一个状态的自动机。

http://en.wikipedia.org/wiki/Reactor_pattern 可能是一个好资源,你的任务。

让客户::断开()函数发送一个事件到eventmanager进行(或服务器)类。这意味着你需要某种事件eventmanager进行(或服务器),事件循环例如处理的。

我的总体思路是,客户端断开::()不立即断开客户机,但只有在回调完成执行。相反,它只是职位将事件eventmanager进行(或服务器)类。

有人可能认为客户端:: disconnect()方法是在错误的类。也许这应该是服务器::断开(客户端* C)。这将是更加符合该服务器“拥有”客户端,它是来断开客户端的服务器的想法(然后更新一些内部簿记)。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top