标签归档:libevent

zmq与libevent共处

可能你会有这种需求,使用zmq来处理消息收发但用libevent来监听描述符。http://inercia.tumblr.com/post/3442759929/zeromq-with-libevent是zmq和libevent混用的一个完整例子。

zmq自己封装的套接字实际上也是关联到linux系统的一个描述符上,因此可以通过getsockopt提取出zmq套接字
对应的系统fd,然后注册到libevent中。不过使用上必须注意一些东西。

1.网上提醒需要先将zmq套接字上的数据全部收完,否则注册到libevent之后的事件响应会有问题,这应该跟zmq的消息分包以及边缘触发有关系。

2.某些模式的zmq套接字与libevent共处会有问题
zmq的模式限制了套接字的收发方向和策略,因此不同模式的zmq套接字会有一些问题,
不过XREQ或者XREP这两种限制较少的模式是ok的。

3.zmq的事件触发是边缘触发,libevent的事件触发是水平触发。因此,每次响应需要把数据收完

4.即便你把上面3条都做了,使用libevent仍然可能会出现丢包的情况,以下是熊哥给出的方案。

让libevent回调到C++类成员函数

libevent是纯C的接口,应用到C++中需要经过一层抽象,如下所示
class A {
public:
void OnRequest(int xx, short yy);
void OnResponse(int xx, short yy);
};

static void OnRequest_cb(int fd, short event, void *args) {
reinterpret_cast(args)->OnRequest(fd, event);
}

static void OnResponse_cb(int fd, short event, void *args) {
reinterpret_cast(args)->OnResponse(fd, event);
}

int main()
{
A *test = new A();
struct event xxx_event;
event_set(&xxx_event, fd, EV_READ|EV_PERSIST, OnRequest_cb, test);
event_add(&xxx_event, NULL);
}