Overview

현재 브랜디는 셀러들에게 풀필먼트서비스를 제공하고 있습니다.
그 중 기본이 되는 상품 바코드, 재고 바코드 등과 같은 재고관리에 필요한 라벨 작업을 하게 되는데,
현재 사용중인 기술에 대해서 소개하려고 합니다.

Contents

  1. 현재 사용중인 기술과 향후 변경 할 기술 소개
  2. WebSocket의 소개
  3. 업무도입 후기와 주의사항
  4. 마무리

1. 현재 사용중인 기술과 향후 변경 할 기술 소개


브랜디는 현재 AWS IoT Core를 활용하여 다양한 라벨 프린팅을 하고 있습니다.
IoT라고 하여 사물인터넷을 떠올리텐데요, AWS IoT Core를 사용하여 센서들의 정보와 센서들과
통신을 하여 다양한 사물 인터넷 환경으로 서비스를 제공 할 수 있지만 MQTT 프로토콜을 활용하여
데이터를 송수신 받아 처리를 할 수도 있습니다.
저희는 MQTT를 사용하여 출력에 필요한 라벨 데이터를 전달 받아 프린팅을 진행하고 있습니다.
다만 AWS IoT를 활용하다 보니 중앙집중식으로 라벨데이터를 주고 받아, 개별 처리 하기에는 무리가 있었습니다. 운영을 하면서 처리량이 많아짐에 따라서 개별로 원하는 정보로만 프린팅을 해야 할 상황이 오자 저희는 다른 기술을 도입하기로 계획했습니다.

저희는 도입 가능한 다양한 프로토콜을 검토하였고, 현재 구축된 웹환경에서 가장 적합한 프로토콜을 정리하였고, 그 중 나온 것이 WebSocket 이었습니다.
그러면 WebSocket이 무엇이고, 이 프로토콜로 어떤 것을 할 수 있을지 같이 알아보도록 하겠습니다.

2. WebSocket의 소개


먼저 WebSocket은 다들 알고 있는대로 TCP Layer 위에서 사용하는 OSI 제7계층에 있는 프로토콜입니다. HTTP 프로토콜과 호환이 되며, 호환이 가능함에 따라서 최초 HTTP 헤더를 사용하여 핸드세이크를 맺고 데이터 송수신을 할 수 있습니다.

그렇다면, 이제 기존 HTTP와는 어떻게 다른지 그림으로 먼저 알아보겠습니다.

1) HTTP 데이터 통신 구조

localizing

2) WebSocket 데이터 통신 구조

localizing

HTTP, WebSocket은 위 그림과 같은 차이가 있습니다.

HTTP는 늘 사용 하는 프로토콜이므로 간단하게 설명을 드리면,
클라이언트가 데이터 요청을 하게 되면 서버는 응답을 해주고 있습니다.
여기서 서버와의 연결은 응답을 받은 후 연결해제 상태가 됩니다.
즉, 1회성으로 연결 → 요청 → 응답 → 해제 의 사이클을 가지고 있습니다.

WebSocket은 기존 HTTP와는 다른 방식의 프로토콜인데요, 단순하게 TCP 프로토콜을 구현하여 사용할 때 1회 연결로 많은 데이터를 송/수신을 할 수 있게 하여 연결 지속성을 가진 커넥션을 만드는 것입니다.

즉, 1회 연결로 많은 데이터 패킷을 주고받을 수 있는 구조 입니다.
연결 → 요청 → 응답 → 요청 → 응답 → … → 해제 의 사이클을 가지고 있습니다.
여기서 요청과 응답은 HTTP처럼 클라이언트 요청 후 응답으로 사용 할 수 있지만
요청만, 혹은 응답만도 가능케 합니다. 여기서 쉽게 응답이라고 표현했지만, 사실상 클라이언트, 서버 모두 메시지를 송/수신 개념으로 바라보는 것이 좋을 듯 합니다.

그럼 어떻게 이렇게 동작을 하는지 동작 원리를 알아 보겠습니다.

흔히 사용자들이 사용하는 브라우저는 크게 IE, Chrome, Safari 가 있습니다.
각 브라우저들은 버전에 따라 다르지만 현재 이 글을 보고 있는 시점에서는 기본적으로 WebSocket 클라이언트 객체를 탑재하고 있습니다. 그래서 웹상에서 손쉽게 웹소켓 클라이언트를 구현 할 수 있습니다.

먼저 클라이언트에서 WebSocket 연결 요청을 HTTP 프로토콜로 요청을 하게 됩니다.
이때는 HTTP 프로토콜의 헤더 영역에 관련 데이터를 포함하여 요청합니다.

3) WebSocket 프로토콜 스위칭 요청 구조

GET /ws HTTP/1.1
Host: server.brandi.co.kr
**Upgrade**: websocket
**Connection**: Upgrade
**Sec-WebSocket-Key**: dGhlIHNhbXBsZSBub25jZQ==
Origin: http://localhost
**Sec-WebSocket-Protocol**: ws
**Sec-WebSocket-Version**: 13

기존에 HTTP API를 요청 할때와 비슷한 구조로 보여집니다. 여기서 차이점이라면 빨간색으로 칠해진 부분일 듯 합니다.

  • Upgrade : 이 값은 websocket 이라고 꼭 들어가야 합니다. 값이 없거나 데이터가 없으면 연결이 종료됩니다.
  • Connection : 이 값은 Upgrade 이라고 꼭 들어가야 합니다. 값이 없거나 데이터가 없으면 연결이 종료됩니다.
  • Sec-WebSocket-Protocol : 클라이언트에서 요청하는 서브 프로토콜을 적어주시면 됩니다. 공백으로 구분하며, 순서에 따라 우선권이 부여됩니다.
  • Sec-WebSocket-Version : 서브 프로토콜의 버전을 적어주시면 됩니다.
  • Sec-WebSocket-Key : 핸드셰이크를 위한 UUID 값입니다. 흔히 Magic Key 라고도 부릅니다. 해당 키는 서버에서 받아서 처리할 때 쓰이는 값이므로 반드시 필요합니다. UUID 32byte값을 Base64로 인코딩하여 전달합니다.

생각보다 간단합니다.
기존 HTTP API와 동일하게 구성되어있고, WebSocket을 위한 몇가지 헤더만 추가 해주면 됩니다.

다음은 핸드셰이크 응답 구조를 보겠습니다.

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
Sec-WebSocket-Protocol: ws

클라이언트 요청과 마찬가지로 HTTP 응답 구조와 동일합니다.

WebSocket 연결요청에 성공하며 HTTP Status Code 101번과 함께 Switching Protocols 을 응답하게 됩니다.

그리고 요청에서 온 헤더값과 추가적인 헤더값들을 응답해줍니다. 여기서 가장 중요한 헤더는 Magic Key의 검증값을 만들어 응답해줘야 합니다. 해당 데이터는 Sec-WebSocket-Accept 헤더를 통하여 응답하게 됩니다.

클라이언트에서 요청 온 Magic Key를 토대로 검증 후 GUID(258EAFA5-E914-47DA-95CA-C5AB0DC85B11)와 같이 붙여서 문자열을 만듭니다. 그 후 GUID가 붙은 Key를 SHA1 Hash값을 Binary 형식으로 만듭니다. 그 데이터를 Base64로 인코딩하여 전달 하게 되면 정상적으로 WebSocket 연결이 성공하게 됩니다.

클라이언트(웹브라우저)가 응답을 받게 되면 새로운 소켓을 열어 프로토콜을 스위칭 하는 작업을 하게 됩니다. 서버에서 응답해준 메시지 그대로 프로토콜 스위칭을 처리하게 됩니다. 그 이후 새로 연결한 소켓을 가지고 데이터 송수신이 이루어지게 됩니다.

현재 저희가 사용하는 WebSocket은연결처리하는 소스중 일부인데요, 아래와 같이 브라우저에 내장되어 있는 WebSocket API를 사용하여 연결, 데이터 전송, 수신 등 비지니스 로직을 개발하여 사용 하시면 됩니다.

4) WebSocket 연결 구현

localizing

5) business Layer 에서 WebSocket Warpping Object 사용 구현

localizing


3. 업무도입 후기와 주의사항


우리는 라벨 프린팅을 AWS IoT → WebSocket으로 변경 후 더 많은 그리고 대량의 라벨 프린팅을 가능하게 구현했습니다. 그리고 중앙처리식이 아닌 개별처리가 가능하게 함으로써 부하 분산에도 큰 도움이 되었습니다.

다만 브라우저에서 WebSocket 을 사용 시 주의사항이 있으니 참고하여 검토 후 서비스에 도입 하시길 추천 드립니다.

  1. HOL Blocking : 네트워크 상황에서 동일한 큐의 앞선 데이터가 지연이 발생한 경우
  2. CORS : 크로스도메인 보안 스펙
  3. 송수신 가능한 최대 용량

4. 마무리


향후 WebSocket을 활용한 다양한 서비스에도 도입 할 수 있을 것 같습니다.
현재도 웹채팅, 상담, 챗봇 등 많은 서비스에서 활용하고 있습니다.
은행, 커머스, 교육 등 분야 등 분야를 막론하고 사용되고 있습니다.

많은 도입사례와 기술 검토, 서비스와의 연계성을 충분히 검토 하여 도입하면
최상의 서비스를 만들 수 있을 것 같습니다.

읽어주셔서 감사합니다.

참고자료

  1. rfc6455
    https://tools.ietf.org/html/rfc6455

장현준 팀장 | 풀필먼트 개발팀
janghj@brandi.co.kr
브랜디, 오직 예쁜 옷만