//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); }
ZeroMQ Router模式C++代码示例
猜你喜欢
转载自blog.csdn.net/wushuangge/article/details/80076927
今日推荐
周排行