[Docker] Dockerfile WebSocket Client/Server Build

2024. 5. 16. 19:07ComputerScience/DockerKubernetes

 

 

 

 

# Dockerfile WebSocket 

https://leimao.github.io/blog/Boost-Docker/

 

Boost C++ Library Docker Container

Portable and Convenient C++ Library

leimao.github.io

 

 

 

 

 

Dockerfile을 통해 빌드

 

 

 

 

 

Websocket build 성공

 

 

 

 

 

docker run

 

 

 

 

 

클라이언트에서 서버 수신

 

 

 

 

 

👩‍💻

Docker desktop을 통해 쉘을 띄워서 클라이언트를 열어도 되고, 

(서버와 클라이언트를 하나의 이미지 파일로 빌드한 경우) 

서로 다른 이미지로 분리하여, 통신을 시킬 수도 있습니다!

 

 

 

 

 

🐳 제출한 Docker hub link 

https://hub.docker.com/repository/docker/sohyeonkimdev/websocket_docker/general

 

Docker

 

hub.docker.com

 

 

 

 

 

# Client 

#include <iostream>
#include <boost/asio.hpp>
#include <boost/beast.hpp>

using namespace boost::asio;
namespace websocket = boost::beast::websocket;

int main() {
    try {
        boost::asio::io_context ioservice; 
        ip::tcp::resolver resolver(ioservice);
        ip::tcp::socket socket(ioservice); 

        // localhost, port number 8080으로 설정 
        auto const results = resolver.resolve("IP_ADDRESS", "8080");

        // 서버 연결 connect 
        boost::asio::connect(socket, results.begin(), results.end()); 

        // Websocket stream
        websocket::stream<ip::tcp::socket> ws(std::move(socket)); 
        ws.handshake("localhost", "/");

        // 클라이언트에서 서버로 message 보내기 (ws write)
        std::string message = "Hello, server!";
        ws.write(boost::asio::buffer(message));

        // 클라이언트가 서버로부터 응답 받기 (ws read)
        boost::beast::multi_buffer buffer;
        ws.read(buffer);
        std::cout << "Received: " << boost::beast::buffers_to_string(buffer.data()) << std::endl;

        ws.close(websocket::close_code::normal);

    } catch (const boost::beast::system_error& e) {
        std::cerr << "Error: " << e.what() << std::endl;
    }
    return 0;
}

 

 

 

 

 

# Server 

#include <iostream>
#include <boost/asio.hpp>
#include <boost/beast.hpp>

using namespace boost::asio;
namespace websocket = boost::beast::websocket;

int main() {
    io_service ioservice;
    // port number 8080 설정 
    ip::tcp::acceptor acceptor(ioservice, ip::tcp::endpoint(ip::tcp::v4(), 8080));
    ip::tcp::socket socket(ioservice);

    acceptor.accept(socket);

    try {
        // websocket stream ws 선언 
        websocket::stream<ip::tcp::socket> ws{std::move(socket)}; 
        ws.accept();

        for (;;) {
            boost::beast::multi_buffer buffer;
            ws.read(buffer);
            ws.text(ws.got_text());
            ws.write(buffer.data());
            // 클라이언트로부터 받은 메세지를 다시 돌려보낸다 (에코 서버)
        }
    } catch (const boost::beast::system_error& e) {
        std::cerr << "Error: " << e.what() << std::endl;
    }

    return 0;
}

 

 

 

 

 

# Dockerfile (server version)

FROM ubuntu:22.04

MAINTAINER SohyeonKim "happythgus@khu.ac.kr"

ARG BOOST_VERSION=1.80.0
ARG CMAKE_VERSION=3.25.1
ARG NUM_JOBS=8

RUN apt-get update && \
    apt-get install -y --no-install-recommends \
        build-essential \
        software-properties-common \
        autoconf \
        automake \
        libtool \
        pkg-config \
        ca-certificates \
        libssl-dev \
        wget \
        git \
        curl \
        language-pack-en \
        locales \
        locales-all \
        vim \
        gdb \
        valgrind && \
    apt-get clean

ENV LC_ALL en_US.UTF-8
ENV LANG en_US.UTF-8
ENV LANGUAGE en_US.UTF-8

# CMake 설치
RUN cd /tmp && \
    wget https://github.com/Kitware/CMake/releases/download/v${CMAKE_VERSION}/cmake-${CMAKE_VERSION}.tar.gz && \
    tar xzf cmake-${CMAKE_VERSION}.tar.gz && \
    cd cmake-${CMAKE_VERSION} && \
    ./bootstrap && \
    make -j${NUM_JOBS} && \
    make install && \
    rm -rf /tmp/*

# BOOST 설치
RUN cd /tmp && \
    BOOST_VERSION_MOD=$(echo $BOOST_VERSION | tr . _) && \
    wget https://boostorg.jfrog.io/artifactory/main/release/${BOOST_VERSION}/source/boost_${BOOST_VERSION_MOD}.tar.bz2 && \
    tar --bzip2 -xf boost_${BOOST_VERSION_MOD}.tar.bz2 && \
    cd boost_${BOOST_VERSION_MOD} && \
    ./bootstrap.sh --prefix=/usr/local && \
    ./b2 install && \
    rm -rf /tmp/*

WORKDIR /app
COPY server.cpp /app
RUN g++ -std=c++17 -o server server.cpp -lboost_system -lboost_thread -pthread

CMD ["./server", "daemon"]

 

Client Image의 경우 하단의 RUN, CMD 부분을 적절히 수정하고, 

각각 생성된 컨테이너 실행 시 Port number 부분만 주의하면 됩니다. :) 

 

 

 

 

 

port number 수정으로, Hello, server 성공! :)