한국어
오픈소스포럼
 이곳은 다양한 오픈소스 프로젝트를 소개하고 리뷰, 활용 방법을 공유합니다.

ZeroMQ 는 고성능 오픈소스 메시징 라이브러리이다. ZeroMQ는 다양한 메시징 패턴을 제공하며 이 팬턴들의 조합으로 다양한 서비스를 구축할 수 있다. 프로세스 내, 프로세스 간, TCP, 멀티캐스트를 포함한 다양한 전송과 함께 작동한다.

Qt기반의 간단한 서버와 클라이언트 프로그램간 통신을 ZeroMQ의 REQ 및 REP 모델을 이용하여 구축해본다. 하나의 요청에 하나의 응답이 이어진다. IP 주소와 포트를 제공하고 장치가 서버(응답 측) 또는 클라이언트(요청 측)인지 결정하기만 하면 된다.

서버 측

C++ 를 위한 헤더전용 바인딩을 사용한다. 가장 먼저 할일은 헤더파일을 포함하는 것이다.

#include <zmq.hpp>

ZeroMQ 는 필수적인 객체를 생성함으로써 시작할 수 있다. 다음은 컨텍스트와 소켓을 생성하는 부분이다. 서버 측은 응답을 수행하므로 소켓 생성 시 플래그socket_type::rep 를 설정한다.

using namespace zmq;
auto context = std::make_unique<context_t>();
auto socket = std::make_unique<socket_t>(*context.get(), socket_type::rep);

서버 측 IP 및 포트를 바인딩한다. 피어가 바인딩된 소켓에 연결할 때 대기열이 생성된다.

socket->bind("tcp://*:5570");
QTimer::singleShot(0, &worker, &Worker::loop);

클라이언트 측

서버 측과 다르게 클라이언트 측은 간단한 UI를 사용자에게 제공한다.

zeromq_client.png

사용자가 메세지를 입력하고 Send 버튼을 클릭하면 서버에 메지시를 보낼 것이다.

컨텍스트와 소켓을 생성하는 부분은 기본적으로 서버 측과 같지만 여기서는 REQ 플래그socket_type::req 로 설정했다는 점이 다르다.

auto context = std::make_unique<context_t>();
auto socket = std::make_unique<socket_t>(*context.get(), socket_type::req);

서버에 연결한다.

socket->connect("tcp://localhost:5570");

Send버튼을 클릭하면 메세지를 보내고 Message Loop를 시작한다.

QString msg = ui->lineEdit->text();
socket->send(message_t(msg.toUtf8()), send_flags::dontwait);
QTimer::singleShot(0, this, &MainWindow::loop);  // Start Message Loop

Message Loop

간단한 폴링을 구현한다. 기본 구현은 요청 및 응답 측 모두에 적용된다. 다음은 간단히 구현한 서버 측 예제이며 수신한 메세지에 "you say " 를 더하여 클라이언트에 다시 보낸다.

void loop(){
    message_t msg;
    socket->recv(msg, recv_flags::dontwait); // 여기서 기다리지 않음.
    size_t size = msg.size();
    if (size) {
        auto message = QString::fromStdString(std::string(reinterpret_cast<char*>(msg.data()), msg.size()));
        qDebug() << message;
        auto echo = "you say " + message;
        socket->send(message_t(echo.toUtf8()), send_flags::dontwait);
    }

    QTimer::singleShot(100, this, &Worker::loop);  // 반복
}

서버와 클라이언트를 빌드하고 실행한 후 클라이언트에서 메세지를 보내본다.

REQ_REP.png

ZeroMQ를 사용하여 간단하게 Qt 응용프로그램 간 통신을 해보았다. 다만 이것은 아주 단순한 형태의 테스트일 뿐이다. 어느정도 규모가 있거나 복잡한 프로젝트에는 적절하지 않을 수 있다.

이런 경우 Qt 응용프로그램을 위한 ZeroMQ 바인딩이 어느 정도 도움이 될 수 있다.