使用C ++的事件驱动的客户端/服务器设计 [英] Event-Driven Client/Server Design with C++

查看:166
本文介绍了使用C ++的事件驱动的客户端/服务器设计的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在设计一个具有脚本功能的游戏服务器。一般设计如下:

I am designing a game server with scripting capabilities. The general design goes like this:

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.

现在最后一部分是对我来说最棘手的。

Now the last part is what's the most tricky for me now.

目前我的设计允许我继承一个类,它继承 Client 来创建对特定接收事件的回调。这些回调在列表中被管理,并且接收的缓冲器在每次接收到事物时经历解析过程。如果缓冲区有效,则调用回调函数,它将根据缓冲区中的内容执行操作。需要注意的一点是,回调可以到脚本引擎,在这一点上没有什么可以确定会发生什么。

Currently my design allows me for a class which inherits Client to create callbacks to specific received events. These callbacks are managed in a list and the received buffer goes through a parsing process each time something is received. If the buffer is valid, the callback is called where it is act upon what is in the buffer. One thing to note is that the callbacks can go down to the scripting engine, at which point nothing is sure what can happen.

每次回调完成,当前接收缓冲区必须被重置等。回调当前没有返回值的能力,因为如前所述,任何事情都可能发生。

Each time a callback finishes, the current receive buffer has to be reset etc. Callbacks currently have no capability of returning a value, because as stated before, anything can happen.

会发生什么是当回调的某处有人说这 - > disconnect(),我想立即断开 Client ,从 EventManager 最后从 Server 中删除​​它,在那里它也应该得到最终破坏和可用内存。但是,我仍然有一些代码运行后回调完成在客户端,因此我不能释放内存。

What happens is that when somewhere in the callback something says this->disconnect(), I want to immediately disconnect the Client, remove it from the EventManager, and lastly remove it from the Server, where it also should get finally destructed and free memory. However, I still have some Code running after the callback finishes in the Client, thus I can't free memory.

我应该在设计中更改什么?我应该在服务器中检查哪些客户端可以自由销毁的时间事件?这会创造额外的开销我不需要?回调完成后在堆栈上运行最小代码( return -1; )还是不行吗?

What should I change in the design? Should I have some timed event in the Server which checks which Clients are free to destroy? Would that create additional overhead I don't need? Would it still be okay after the callback finishes to run minimal code on the stack (return -1;) or not?

我不知道该怎么做,但我可以进行完整的设计改进。

I have no idea what to do, but I am open for complete design revamps.

提前感谢。

推荐答案

您可以使用引用计数指针,如 boost :: shared_ptr<> 来简化内存管理。如果管理器的客户端列表使用 shared_ptr ,并且调用回调的代码创建了 shared_ptr 的本地副本则对象将保持活动状态,直到它从管理员中移除并且回调函数完成:

You can use a reference counted pointer like boost::shared_ptr<> to simplify memory management. If the manager's client list uses shared_ptrs and the code that calls the callbacks creates a local copy of the shared_ptr the callback is called on, the object will stay alive until it is removed from the manager and the callback function is complete:

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 的本地副本,确保对象未意外删除。

The Client object will automatically be deleted once the last shared_ptr to it goes out of scope, but not before. So creating a local copy of the shared_ptr before a function call makes sure the object is not deleted unexpectedly.

这篇关于使用C ++的事件驱动的客户端/服务器设计的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆