zmq req重试机制

来源:互联网 发布:windows界面开发 编辑:程序博客网 时间:2024/04/28 14:13
ref: http://www.oschina.net/question/565065_116643
#include <zmq.h>#include <string.h>#include <stdio.h>#include <unistd.h>#define SERVER_ENDPOINT "tcp://localhost:5555"#define REQUEST_TIMEOUT 3000 // msecs, (> 1000!)#define REQUEST_RETRIES 3 // retry before we abandonvoid *zmq_socket_new (void *context){    int linger = 1;    void *zsocket = zmq_socket (context, ZMQ_REQ);    zmq_setsockopt(zsocket, ZMQ_LINGER, &linger, sizeof(linger));    zmq_connect (zsocket, SERVER_ENDPOINT);    return zsocket;}int main (void){    void *context = zmq_ctx_new ();    void *zsocket = zmq_socket_new(context);    char buffer [255];    char *send_s = "Hello";    int retries_left = REQUEST_RETRIES;    while (retries_left) {        // 发送消息        zmq_send (zsocket, send_s, strlen(send_s), 0);        printf ("Send %s\n", send_s);        // 重试次数        int expect_reply = 1;        while (expect_reply) {            // 停止重试            if (retries_left == 0) {                printf("Server offline, abandoning ...\n");                break;            }            // 多路复用            zmq_pollitem_t items [] = { { zsocket, 0, ZMQ_POLLIN, 0 } };            int rc = zmq_poll (items, 1, REQUEST_TIMEOUT);            if (rc == -1) break; // Interrupted            if (items [0].revents & ZMQ_POLLIN) {                // 接收反馈                int size = zmq_recv (zsocket, buffer, 10, 0);                if (size > 255) size = 255;                buffer[size] = 0;                printf ("Recv %s\n", buffer);                if (buffer) {                    retries_left = REQUEST_RETRIES;                    expect_reply = 0;                }            }            // 重试连接            else {                printf("Retry connecting ...\n");                zmq_close (zsocket);                zsocket = zmq_socket_new(context);                // 重发消息                zmq_send (zsocket, send_s, strlen(send_s), 0);                printf ("Send %s\n", send_s);                --retries_left;            }        }    }    zmq_close (zsocket);    zmq_ctx_destroy (context);    return 0;}

以上的设计模式被称之为“客户端信任”的模式,通过这种设计,我们建立了一个可控的、相对稳定的 C/S 通信模型。当然,从以上代码中我们也可以看到 ZeroMQ 中多路复用的用法,也就是 int zmq_poll (zmq_pollitem_t *items, int nitems, long timeout); 方法的使用,三个参数分别是 poll 项列表、poll 项个数以及 poll 超时时间(毫秒),其中 zmq_pollitem_t 的结构如下: 

typedef struct 

    void //*socket//; 
    int //fd//; 
    short //events//; 
    short //revents//; 
} zmq_pollitem_t; 

此外,ZeroMQ 支持多种多路复用模式(参考源码 poller.hpp),列举如下: 

1、select(支持unix/windows) 
2、poll(支持unix) 
3、epoll(支持linux) 
4、kqueue(支持freebsd) 
5、devpoll(zmq自研的poll) 

其中,Linux 下默认使用的是 epoll 方式;当然,在编译的时候也可以通过 --with-poller 参数来配置所需的多路复用模式。
原创粉丝点击