ZeroMQ Router模式C++代码示例

//Linux下可编译通过
#include <cstdio>
#include <cassert>
#include <thread>
#include <chrono>
#include <memory>
#include <vector>
#include <zmq.h>
#include <string.h>
#include<iostream>

using namespace std;

#define printError()    printf("%s[%d]: %d: %s\n", __FILE__, __LINE__, \
    zmq_errno(), zmq_strerror(zmq_errno()));


static void create_broker(void* context, const char* front_addr, const char* back_addr);
static void create_worker(void* context, const char* addr);
static void create_client(void* context, const char* addr);


int main(int argc, char* argv[])
{
    int major, minor, patch;
    zmq_version(&major, &minor, &patch);
    int version = ZMQ_MAKE_VERSION(major, minor, patch);
    if (version < ZMQ_VERSION)
    {
        printf("zmq library expect version %d but get %d.\n", ZMQ_VERSION, version);
        return 1;
    }

    void *context = zmq_ctx_new();
    const char* front_addr = "tcp://127.0.0.1:5559";
    const char* back_addr = "tcp://127.0.0.1:5560";

    // create broker
    auto broker = make_shared<thread>(create_broker, context, front_addr, back_addr);

    // create worker
    vector<shared_ptr<thread>> workers;
    for (int i = 0; i < 1; i++)
    {
        auto worker = make_shared<thread>(create_worker, context, back_addr);
        workers.emplace_back(worker);
    }

    // create clients
    vector<shared_ptr<thread>> clients;
    for (int i = 0; i < 1; i++)
    {
        auto client = make_shared<thread>(create_client, context, front_addr);
        clients.emplace_back(client);
    }

    if (broker)
    {
        broker->join();
    }
    for (auto worker : workers)
    {
        worker->join();
    }
    for (auto client : clients)
    {
        client->join();
    }

    zmq_ctx_destroy(context);

    return 0;
}


void create_worker(void* context, const char* addr)
{
    assert(context && addr);
    void* responder = zmq_socket(context, ZMQ_REP);
    int r = zmq_connect(responder, addr);
    if (r == -1)
    {
        printError();
        zmq_close(responder);
        return;
    }

    //auto thread_id = this_thread::get_id().hash();
    auto thread_id =  pthread_self();
    printf("worker %u started...\n", thread_id);
    while (true)
    {
        zmq_msg_t msgIn;
        zmq_msg_init(&msgIn);
        r = zmq_msg_recv(&msgIn, responder, 0);
        if (r == -1)
        {
            printError();
            break;
        }
        printf("[%u]Received request: %s\n", thread_id, (char*)zmq_msg_data(&msgIn));
        zmq_msg_close(&msgIn);

        //发送消息
        zmq_msg_t msgOut;
        zmq_msg_init_size (&msgOut, 6);
        memcpy(zmq_msg_data (&msgOut), "WORLD", 6);
        r = zmq_msg_send(&msgOut,responder,0);
        if (r == -1)
        {
            printError();
            break;
        }
        //cout << "send:" << (char*)zmq_msg_data(&msgOut) << endl;
        zmq_msg_close (&msgOut); // 释放和销毁消息
        this_thread::sleep_for(chrono::milliseconds(1));
    }
    zmq_close(responder);
    printf("worker %u closed...\n", thread_id);
}


void create_broker(void* context, const char* front_addr, const char* back_addr)
{
    assert(context && front_addr && back_addr);
    void* frontend = zmq_socket(context, ZMQ_ROUTER);
    void* backend = zmq_socket(context, ZMQ_DEALER);
    assert(frontend && backend);
    int r = zmq_bind(frontend, front_addr);
    assert(r == 0);
    r = zmq_bind(backend, back_addr);
    assert(r == 0);

    printf("broker started...\n");
    zmq_proxy(frontend, backend, NULL);

#if 1
    zmq_pollitem_t items[] =
    {
        { frontend, 0, ZMQ_POLLIN, 0 },
        { backend, 0, ZMQ_POLLIN, 0 },
    };
    while (true)
    {
        zmq_msg_t message;
        r = zmq_poll(items, 2, -1);
        if (r == -1)
        {
            printError();
            break;
        }
        if (items[0].revents & ZMQ_POLLIN)
        {
            while (true)
            {
                zmq_msg_init(&message);
                r = zmq_msg_recv(&message, frontend, 0);
                if (r == -1)
                {
                    printError();
                    break;
                }
                int more = zmq_msg_more(&message);
                r = zmq_msg_send(&message, backend, more ? ZMQ_SNDMORE : 0);
                if (r == -1)
                {
                    printError();
                    zmq_msg_close(&message);
                    break;
                }
                zmq_msg_close(&message);
                if (!more)
                    break;
            }
        }
        if (items[1].revents & ZMQ_POLLIN)
        {
            while (true)
            {
                zmq_msg_init(&message);
                r = zmq_msg_recv(&message, backend, 0);
                if (r == -1)
                {
                    printError();
                    zmq_msg_close(&message);
                    break;
                }
                int more = zmq_msg_more(&message);
                r = zmq_msg_send(&message, frontend, more ? ZMQ_SNDMORE : 0);
                if (r == -1)
                {
                    printError();
                    zmq_msg_close(&message);
                    break;
                }
                zmq_msg_close(&message);
                if (!more)
                    break;
            }
        }
    }
#endif

    zmq_close(frontend);
    zmq_close(backend);
    printf("broker[%d] closed...\n", pthread_self());
}


void create_client(void* context, const char* addr)
{
    assert(context && addr);
    void* requester = zmq_socket(context, ZMQ_REQ);
    assert(requester);
    int r = zmq_connect(requester, addr);
    if (r == -1)
    {
        printError();
        zmq_close(requester);
        return;
    }
    auto thread_id =  pthread_self();
    printf("client %u started...\n", thread_id);
    int request_nbr = 10;
    for (int i = 0; i < request_nbr; i++)
    {
        zmq_msg_t msgOut;
        zmq_msg_init_size (&msgOut, 6);
        memcpy (zmq_msg_data (&msgOut), "hello", 6);
        r = zmq_msg_send(&msgOut,requester,0);
        if (r == -1)
        {
            printError();
            break;
        }
        //cout << "send:" << (char*)zmq_msg_data(&msgOut) << endl;
        zmq_msg_close (&msgOut);

        zmq_msg_t msgIn;
        zmq_msg_init(&msgIn);
        r = zmq_msg_recv(&msgIn, requester, 0);
        if (r == -1)
        {
            printError();
            break;
        }
        printf("[%u]Received reply %d [%s]\n", thread_id, i, (char*)zmq_msg_data(&msgIn));
       // cout << "recv:" << (char*)zmq_msg_data(&msgIn) << endl;
        zmq_msg_close(&msgIn);

        this_thread::sleep_for(chrono::milliseconds(10));
    }
    zmq_close(requester);
    printf("client %u closed...\n", thread_id);
}

猜你喜欢

转载自blog.csdn.net/wushuangge/article/details/80076927
今日推荐