-
[ZeroMQ] Mac Os BigSur & Linux Ubuntun 18.04 에서 설치 및 helloworld 테스트Computer Programs 2021. 6. 28. 15:31
ZeroMQ는 다양한 전송 프로토콜을 제공하며, 대용량 데이터 처리에 적합한 오픈소스 메시지 지향 미들웨어.
PUB 소켓에서 채널에 데이터를 브로드 캐스팅 하면, SUB 소켓에서 필터링을 통해 원하는 데이터를 채널로부터 취득하는 방식으로 동작한다.
https://zguide.zeromq.org/docs/chapter1/
Tutorial 따라서 ZeroMQ 파헤치기
chapter 1. Basic
https://zeromq.org/get-started/?language=cpp&library=zmqpp#
일단 먼저 라이브러리를 설치해야한다. ( libzmq 설치 )
https://github.com/zeromq/cppzmq
linux에서는
요기서 잘 골라가지고 설치파일 다운받아서 설치하믄 끝.
나같은 경우에는
latest relase 에서 obs master stable 눌러서
os ubuntu 선택하고, github에서 설치하거나 binary 파일 받아서 설치하거나 둘 중 고르라고 하는데 binary 파일 선택해서
ubuntu 18.04 쓰니까 여기서 내 컴 사양 맞게 amd64고르고 다운로드 받아서 설치
그냥 더블 클릭하면 앱스토어같은거 열리고 거기서 install 버튼 눌러서 설치하믄 끝.
https://github.com/zeromq/cppzmq
https://github.com/zeromq/cppzmq
mac os에서는 brew로 한 방설치가능 ( 근데 brew는 C++이랑 링킹안해주기때문에 cmakelist 적거나 매크로 잘 적어서 컴파일 해줘야한다 )
brew install zeromq
** 만약 컴파일 하는데 zmq.hpp가 없다고 그러면
cppzmq를 클론해서 폴더 안에 .hpp 헤더파일을 /usr/local/include에 직접 복붙 해줘야한다.
git clone https://github.com/zeromq/cppzmq.git
그 다음에 언어 C++ 로 테스트 할 것이기 때문에 C++ 선택하고,
라이브러리를 선택해야하는테 cppzmq이게 젤 처음으로 나와있고, 예제 코드도 익숙해보여서 이것으로 선택
test 디렉토리 하나 만들어주고
여기서 바로 터미널 명령창에서 컴파일 할꺼면
g++ -std=c++17 server.cpp -o server -L/usr/local/lib -lzmq
이걸로 컴파일해서 ./server 로 실행시키거나
CMakeLists.txt 파일 만들어서
cmake_minimum_required(VERSION 3.19) project( server ) set(CMAKE_CXX_STANDARD 17) INCLUDE_DIRECTORIES(/usr/local/include) LINK_DIRECTORIES(/usr/local/lib) set(SRC_FILES server.cpp) ADD_EXECUTABLE(${PROJECT_NAME} ${SRC_FILES}) TARGET_LINK_LIBRARIES(${PROJECT_NAME} zmq)
요로코롬~ 만들어서
build 폴더 생성해서 거기서 cmake .. && make 해주면 실행파일 project_name으로 설정해준 것 생김.
그 다음 또 새로운 터미널 창열어서 거기서 client 컴파일 해주고,
./server 먼저 실행하고 ./client 실행하면 서로 Hello랑 World 주고받으면서 zmq 테스트 가능.
아래는 server.cpp랑 client.cpp
//server.cpp #include <string> #include <chrono> #include <thread> #include <iostream> #include <zmq.hpp> int main() { using namespace std::chrono_literals; // initialize the zmq context with a single IO thread zmq::context_t context{1}; // construct a REP (reply) socket and bind to interface zmq::socket_t socket{context, zmq::socket_type::rep}; socket.bind("tcp://*:5555"); // prepare some static data for responses const std::string data{"World"}; for (;;) { zmq::message_t request; // receive a request from client socket.recv(request, zmq::recv_flags::none); std::cout << "Received " << request.to_string() << std::endl; // simulate work std::this_thread::sleep_for(1s); // send the reply to the client socket.send(zmq::buffer(data), zmq::send_flags::none); } return 0; }
//client.cpp #include <string> #include <chrono> #include <thread> #include <iostream> #include <zmq.hpp> int main() { using namespace std::chrono_literals; // initialize the zmq context with a single IO thread zmq::context_t context{1}; // construct a REP (reply) socket and bind to interface zmq::socket_t socket{context, zmq::socket_type::rep}; socket.bind("tcp://*:5555"); // prepare some static data for responses const std::string data{"World"}; for (;;) { zmq::message_t request; // receive a request from client socket.recv(request, zmq::recv_flags::none); std::cout << "Received " << request.to_string() << std::endl; // simulate work std::this_thread::sleep_for(1s); // send the reply to the client socket.send(zmq::buffer(data), zmq::send_flags::none); } return 0; }
위 사이트에 있는 예제 코드 server와 client 코드파일 각각 하나씩 생성
Hello world example의 기본 request - reply 구조.
클라이언트는 루프에서 zmq_send() 후에 zmq_recv()를 하고있고,
서버는 루프에서 zmq_recv() 후에 zmq_send()를 하고있다.
가장 심플한 request-reply 모델이며, zeroMQ를 사용하기위한 가장 쉬운 방법.
이것은 RPC classic의 client/server model에도 맵핑된다.
test결과
추가
** 문자열에 대한 사소한 참고
ZeroMQ는 바이트 단위 크기 제외하고 전송하는 데이터에 대해 아무것도 알지 못한다.
즉 ,, 응용 프로그램이 다시 읽을 수 있도록 안전하게 포맷해야한다. ( 클라이언트와 서버가 문자열 형식이 동일하지 않으면 이상한 결과가 나타난다. )
따라서 규칙 -> ZeroMQ 문자열이 길이가 지정되고, 후행 null 없이 wire로 전송된다고 가정.
위처럼 편리하게 도우미 함수로 만들어서 재사용하면 올바른 ZeroMQ 형식으로 문자열을 전송할 수 있게도니다.
publish-subscribe 구조
*NOTE ) sub socket이라면, 꼭 zmq_sdetsockopt()로 subscription을 설정하고 subscribe 해야한다.
*NOTE ) pub socket에서는 zmq_recv()를 하지 않도록 주의 ( 무조건 zmq_send() 만 )
Points
- subscriber는 1개 이상의 publisher에 동시에 연결할 수 있다.
- 연결된 sub가 없으면 pub는 모든 메시지를 drop한다
Divide and Conquer _ Paralle Pipeline
ventilator가 병렬로 처리할 수 있는 task를 worker들에게 push 하게 되고, worker들이 task를 병렬로 처리하고, sink가 worker process로 부터 result를 모으게 된다.
'Computer Programs' 카테고리의 다른 글
[Capnp] Cap'n Proto 란 (0) 2022.11.07 [Protocol Buffer] google protobuf 란 (0) 2021.06.29 [ZeroMQ] Socket 생성 및 동작 확인 및 구현 (0) 2021.06.29 [CMake] CMakeLists.txt 작성하기 (0) 2021.06.28