키오스크는 화면보다 장치를 먼저 붙입니다 — 하드웨어 연동 시스템의 개발 순서와 설계 기준

키오스크 프로젝트의 산출물 목록을 보면 화면 설계서가 가장 앞에 있습니다. 그래서 개발도 화면부터 시작하는 경우가 많습니다. 대기 화면을 만들고, 선택 화면을 만들고, 결제 화면을 만든 다음 마지막에 장치를 붙입니다.

저희는 이 순서를 뒤집어서 진행합니다. 화면을 그리기 전에 장치와 통신이 되는지부터 확인합니다. 키오스크에서 일정이 무너지는 지점은 거의 항상 장치 연동이고, 그 문제는 화면이 완성된 뒤에 발견될수록 비용이 커지기 때문입니다.

이 글은 저희가 구축한 세 가지 키오스크를 바탕으로 썼습니다.

프로젝트 설치 환경 붙인 장치 구성
시험장 신분 확인 키오스크 국가 자격시험 CBT 시험장 신분 확인 장비, 외부 시험 운영 시스템 Windows 데스크톱 앱(Electron)
플라스틱 컵 무인 수거 키오스크 카페·상가·공공시설, 200대 이상 분쇄 장치 Android 앱(React Native)
숙박 셀프 체크인 키오스크 숙박 시설 로비 결제 단말(VAN), 신분증 카메라, 도어락 Android 앱 + 웹 화면

하드웨어 선정이나 접근성 법규처럼 착수 전에 확인할 항목은 키오스크 구축 체크리스트에서 따로 다뤘습니다. 이 글은 그 다음 단계, 즉 실제로 어떤 순서로 개발했고 구조를 어떻게 잡았는지에 대한 이야기입니다.


1. 개발 순서: 장치 연동부터 확인합니다

장치 연동을 마지막에 두면 문제가 화면이 완성된 뒤에 드러납니다

연동이 되는지가 일정의 가장 큰 변수입니다

세 프로젝트의 장치는 연결 방식이 모두 달랐습니다.

장치 연결 방식 먼저 확인한 것
신분 확인 장비 제조사가 제공한 네이티브 라이브러리를 앱에서 직접 호출 라이브러리 호출이 안정적으로 끝나는가, 한 번 판독에 얼마나 걸리는가
분쇄 장치 시리얼 통신으로 명령 전송, 상태 수신 신호가 어떤 순서로 오는가, 중복이나 누락이 있는가
결제 단말 단말에 설치된 VAN사 결제 프로그램을 앱이 호출 승인 요청 전에 무엇을 점검해야 하는가, 실패하면 어떤 코드가 오는가

이 질문들의 답은 문서만으로는 얻기 어렵습니다. 연동 규격서에는 정상 동작이 적혀 있고, 실제 일정을 잡아먹는 것은 규격서에 없는 동작입니다. 장치가 응답하지 않을 때 얼마나 기다려야 하는지, 같은 신호가 두 번 오는지, 오류 코드가 실제로 어떤 상황에서 나오는지는 장치를 책상 위에 올려놓고 호출해 봐야 알 수 있습니다.

시험장 키오스크는 4개월 일정 중 가장 먼저 장비 라이브러리 호출을 확인했고, 호출이 안정적으로 동작하는 것을 본 뒤에야 나머지 일정을 확정했습니다. 수거 키오스크도 분쇄 장치와 시리얼 통신으로 명령을 주고받는 부분을 먼저 확보한 뒤 그 위에 화면을 얹었습니다.

저희가 따르는 순서

  1. 장치 단독 검증 — 화면 없이 장치만 호출하는 최소 코드로 정상·실패·무응답을 확인합니다
  2. 장치 경계 정의 — 화면이 장치에 요청할 수 있는 동작과 돌려받는 결과의 형식을 정합니다
  3. 흐름 정의 — 대기부터 완료까지의 단계와 단계 사이의 이동 조건을 정합니다
  4. 화면 구현 — 이 시점에서 화면은 정해진 흐름에 표시만 입히는 작업이 됩니다
  5. 운영 기능 — 원격 갱신, 로그, 관리자 진입, 장비 식별
  6. 현장 조정 — 실제 설치 장소에서만 드러나는 문제를 반영합니다

1번에서 얻은 숫자가 뒤 단계의 설계값이 됩니다. 판독에 5초가 걸리는 장비라면 진행 화면은 그 시간을 버틸 수 있게 만들어야 하고, 제한 시간은 그보다 충분히 길게 잡아야 합니다. 이 숫자를 모른 채 화면을 먼저 만들면 나중에 화면 구성을 다시 손보게 됩니다.


2. 화면과 장치 사이에 경계를 둡니다

화면은 장치를 직접 다루지 않고 정해진 통로로만 요청합니다

화면은 장치를 모릅니다

세 프로젝트 모두 화면 코드가 장치를 직접 호출하지 않습니다. 화면은 "신분 확인을 시작해 달라", "결제를 요청한다" 같은 동작을 요청하고, 성공 여부와 결과 값을 돌려받습니다. 장치의 함수 이름이나 통신 형식은 경계 안쪽에만 있습니다.

이렇게 나누는 이유는 장치가 바뀌기 때문입니다. 시험장 장비는 조달 상황에 따라 다른 모델로 교체될 수 있고, 결제 단말은 계약하는 VAN사에 따라 연동 방식이 달라집니다. 경계가 없으면 장치가 바뀔 때 화면 흐름 전체를 다시 확인해야 합니다. 경계가 있으면 안쪽만 바꾸고 화면은 그대로 둡니다.

장치 호출은 별도 프로세스에서 실행합니다

시험장 키오스크에서 신분 확인 장비는 제조사가 제공한 네이티브 라이브러리로 제어합니다. 이 라이브러리 호출을 앱 본체에서 직접 하지 않고, 판독 한 번마다 별도 프로세스를 띄워 그 안에서 실행합니다.

네이티브 라이브러리는 오류가 났을 때 예외를 던지는 대신 프로세스를 통째로 종료시키는 경우가 있습니다. 앱 본체에서 호출하면 그 순간 키오스크 화면이 사라지고, 무인 환경에서는 누군가 와서 다시 켜 줄 때까지 장비가 멈춥니다. 별도 프로세스로 분리해 두면 장치 쪽에서 문제가 생겨도 종료되는 것은 그 프로세스뿐이고, 앱은 "판독 실패"라는 결과를 받아 실패 화면으로 넘어갑니다.

제한 시간도 이 경계에서 겁니다. 판독 프로세스가 15초 안에 끝나지 않으면 강제로 종료하고 실패로 처리합니다. 장치가 응답 없이 멈춰 있어도 화면은 15초 뒤에는 반드시 다음 단계로 넘어갑니다.

시스템 권한은 화면에서 떼어 둡니다

키오스크는 불특정 다수가 만지는 장비입니다. 장치 제어, 파일 접근, 전원 종료처럼 시스템 권한이 필요한 작업은 화면을 그리는 쪽이 아니라 권한을 가진 쪽에서만 수행하고, 화면은 정해진 통로로 요청만 보냅니다.

숙박 체크인 키오스크는 같은 원칙을 다른 형태로 적용했습니다. 화면은 웹으로 만들고, Android 앱이 그 화면을 띄우면서 결제 단말과 카메라를 맡습니다. 화면을 웹으로 둔 이유는 문구나 배치 수정이 잦기 때문이고, 장치를 앱에 둔 이유는 웹이 장치에 직접 접근할 수 없기 때문입니다. 웹 화면이 결제를 요청하면 앱이 단말과 통신한 뒤 결과를 화면에 돌려줍니다.


3. 장치 신호는 그대로 믿지 않습니다

장치가 보내는 신호를 화면 상태에 곧바로 연결하면 문제가 생깁니다. 세 프로젝트에서 공통으로 적용한 규칙입니다.

규칙 적용 사례 지키지 않으면
모든 호출에 제한 시간을 둔다 신분 확인 15초, 결제 요청 3분, 상태 조회 15초 장치가 멈추면 화면도 함께 멈춤
한 번에 하나만 요청한다 결제 진행 중에는 새 결제 요청을 거절 응답이 어느 요청의 것인지 알 수 없음
중복과 순서 뒤바뀜을 정리한다 분쇄 장치 신호를 이벤트 흐름으로 받아 정리한 뒤 화면에 반영 진행 표시가 튀거나 수량이 두 번 집계됨
받은 데이터의 끝을 확인한다 길이를 먼저 읽고 그만큼 모일 때까지 기다림 잘린 데이터를 해석하다 오류 발생

한 번에 하나만

결제 단말에 요청을 보내 놓고 응답을 기다리는 동안 두 번째 요청이 들어가면, 돌아온 응답이 어느 요청의 것인지 구분할 수 없습니다. 그래서 진행 중인 요청이 있으면 새 요청은 즉시 "처리 중"으로 거절합니다.

여기에 한 가지를 더 둡니다. 응답이 끝내 오지 않으면 "진행 중" 표시가 풀리지 않아 이후의 모든 결제가 거절됩니다. 그래서 45초가 지나도 응답이 없는 요청은 스스로 정리하도록 했습니다. 잠금을 걸 때는 그 잠금이 풀리지 않는 경우를 함께 설계해야 합니다.

신호는 중복되고 순서가 바뀝니다

분쇄 장치에서 시리얼 통신으로 들어오는 신호는 같은 내용이 두 번 오기도 하고 순서가 어긋나기도 합니다. 이 신호를 그대로 화면에 연결하면 "투입 수량"이 한 번에 두 개씩 올라가거나, 완료 표시가 진행 표시보다 먼저 나타납니다.

수거 키오스크에서는 장치 신호를 이벤트 흐름으로 받아 중복을 걸러 내고 순서를 맞춘 다음 화면 상태로 넘깁니다. 화면에 표시되는 수량은 곧 포인트로 이어지기 때문에, 이 정리 단계가 없으면 표시 오류가 정산 오류가 됩니다.

데이터는 나뉘어서 도착합니다

시험장 키오스크는 외부 시험 운영 시스템과 TCP 소켓으로 수험자 명단을 주고받습니다. 소켓으로 보낸 데이터는 한 번에 도착한다는 보장이 없습니다. 명단이 길면 여러 조각으로 나뉘어 들어옵니다.

그래서 모든 메시지 앞에 4바이트의 길이 값을 붙이고, 받는 쪽은 길이를 먼저 읽은 뒤 그만큼의 데이터가 모일 때까지 기다렸다가 해석합니다. 개발 환경에서는 명단이 짧아 항상 한 번에 도착하므로 이 처리가 없어도 문제가 드러나지 않습니다. 수험자가 많은 실제 시험장에서 처음 나타나는 종류의 오류입니다.


4. 화면 흐름: 한 화면에 한 가지 결정

신분 확인 키오스크의 화면 흐름 — 정상 경로와 예외 경로를 나눴습니다

흐름을 한 방향으로 만듭니다

시험장 키오스크의 화면은 다음 순서로 이어집니다.

대기 → 수험 정보 입력 → 신분증 놓는 방법 안내 → 수집 동의 → 판독 → 성공 또는 실패 → 좌석 안내 → 대기

화면 하나는 하나의 역할만 맡습니다. 입력 화면에서는 입력만, 안내 화면에서는 안내만 합니다. 시험 직전의 수험자는 긴장한 상태이고, 한 화면에서 판단할 것이 두 가지 이상이면 그 자리에서 멈춥니다. 한 명이 멈추면 뒤에 선 줄 전체가 멈춥니다.

현재 단계를 한 곳에서 관리합니다

화면마다 "다음은 어디로 간다"를 따로 적어 두면, 뒤로 가기와 처음으로 돌아가기가 화면마다 다르게 동작하기 시작합니다. 시험장 키오스크에서는 진행 단계를 입력, 신분 확인, 좌석 안내 세 단계로 정의하고, 다음·이전·초기화 세 가지 동작으로만 단계를 바꿉니다. 어느 화면에서 초기화를 누르든 같은 지점으로 돌아갑니다.

예외는 줄 밖으로 뺍니다

판독에 실패하면 실패 화면으로 넘어가 다시 시도하거나 진행 요원에게 문의하도록 안내합니다. 실패를 판독 화면 안에서 계속 재시도하게 두지 않는 이유는, 붐비는 시간대에는 평균 처리 시간보다 가장 오래 걸리는 한 명이 전체 처리량을 결정하기 때문입니다.

입력 단계에도 같은 원칙을 적용했습니다. 수험번호로 조회했는데 일치하는 사람이 여러 명이면 선택 창을 띄우고, 일치하는 사람이 없으면 안내 창을 띄웁니다. 정상 경로는 짧게 두고, 예외는 별도 화면에서 처리합니다.

키보드가 없는 환경의 입력

키오스크에는 키보드가 없습니다. 수험번호 8자리나 주민등록번호 13자리를 입력받기 위해 화면 키패드를 별도 컴포넌트로 만들었습니다. 숫자, 초기화, 뒤로 가기만 있는 단순한 구성입니다. 숙박 키오스크에서도 예약번호와 전화번호 조회에 같은 방식의 키패드를 씁니다.

사람이 떠난 화면은 스스로 돌아갑니다

무인 장비에서 가장 흔한 문제는 앞 사용자가 중간 화면에 머문 채 자리를 뜨는 것입니다. 개인정보가 표시되는 화면은 특히 그렇습니다.

  • 시험장 키오스크의 좌석 안내 화면 — 10초 뒤 대기 화면으로 복귀
  • 숙박 키오스크의 체크인 완료 화면 — 30초 뒤 복귀
  • 수거 키오스크 — 일정 시간 조작이 없으면 어느 화면에서든 대기 화면으로 복귀

복귀 시간은 화면에 표시된 정보를 읽는 데 필요한 시간으로 정합니다. 좌석 번호는 10초면 충분하지만, 객실 번호와 출입 비밀번호는 사진을 찍거나 옮겨 적는 시간이 필요합니다.


5. 결제 단말: 실패보다 애매한 상태가 어렵습니다

결제는 키오스크에서 가장 까다로운 장치입니다. 실패는 다루기 쉽습니다. 어려운 것은 성공했는지 알 수 없는 상태입니다.

승인 전 점검부터 서버 등록까지, 단계마다 실패했을 때의 처리를 정했습니다

승인을 요청하기 전에 점검합니다

숙박 키오스크는 승인 요청을 바로 보내지 않습니다. 먼저 카드 리더가 응답하는지 확인하고, 단말이 거래 가능한 상태인지 확인한 다음에 승인을 요청합니다. 리더가 응답하지 않는 상태에서 승인 요청을 보내면 이용자는 카드를 꽂은 채 제한 시간이 끝날 때까지 기다리게 됩니다. 점검에서 걸러 내면 몇 초 안에 "지금은 카드 결제가 어렵다"고 안내할 수 있습니다.

통신 오류는 한 번만 복구를 시도합니다

단말과의 통신 오류가 나면 정해진 복구 절차(통신 재설정, 리더 초기화, 리더 재점검)를 수행한 뒤 결제를 한 번만 다시 시도합니다. 횟수를 한 번으로 제한한 이유는 결제이기 때문입니다. 원인을 모르는 채 여러 번 재시도하면 이중 승인의 위험이 커집니다.

승인은 됐는데 서버가 모르는 경우

가장 곤란한 상황은 단말에서 카드 승인이 끝났는데, 그 결과를 서버에 등록하는 요청이 실패한 경우입니다. 이용자의 카드에서는 돈이 나갔지만 시스템에는 결제 기록이 없습니다.

이 경우 키오스크는 세 가지를 합니다.

  1. 승인 내역을 장비 안에 별도 기록으로 남깁니다
  2. 예약을 확정하지 않습니다
  3. 화면에 "결제는 완료되었으나 처리가 끝나지 않았다"는 사실과 함께 직원 호출을 안내합니다

자동으로 취소하거나 자동으로 확정하지 않는 것이 핵심입니다. 어느 쪽이든 추측으로 처리하면 틀렸을 때 되돌리기 어렵습니다. 기록을 남기고 사람이 확인하는 경로로 넘기는 편이 안전합니다.

중복 결제를 줄이기 위한 장치도 함께 둡니다. 주문 번호는 서버가 발급한 값을 단말 거래의 관리 번호로 넘기고, 확정 처리가 진행 중일 때는 2분 동안 같은 확정 요청이 다시 들어가지 않도록 잠급니다.

원격 취소는 두 경로로 받습니다

관리자가 사무실에서 결제를 취소하면, 실제 카드 취소는 그 카드를 승인한 단말에서 실행해야 합니다. 서버가 키오스크에 "이 거래를 취소해 달라"고 알려야 합니다.

이 알림은 두 경로로 받습니다. 평소에는 서버와 연결된 웹소켓으로 즉시 받고, 연결이 끊긴 경우에 대비해 5초마다 대기 중인 취소 요청이 있는지 조회합니다. 같은 요청이 양쪽으로 들어올 수 있으므로 이미 처리 중이거나 처리한 요청은 걸러 냅니다.

취소 결과를 서버에 보고하는 일도 실패할 수 있습니다. 보고는 1초, 2초, 4초 간격으로 세 번 재시도하고, 그래도 실패하면 장비 안의 대기열에 보관합니다. 보관한 결과는 앱이 켜질 때와 이후 60초마다 다시 전송합니다. 카드 취소는 이미 끝났는데 시스템에는 취소 전으로 남는 상황을 막기 위한 장치입니다.

운영하면서 고친 것

초기에는 등록된 모든 키오스크가 5초마다 취소 요청을 조회했습니다. 결제 단말이 없는 키오스크도 마찬가지였습니다. 장비 수가 늘면서 의미 없는 조회가 서버에 계속 쌓였습니다.

키오스크가 서버에서 받는 설정에 결제 단말 사용 여부를 넣고, 사용하지 않는 장비는 웹소켓 연결과 조회를 모두 건너뛰도록 고쳤습니다. 이때 설정 값이 없는 경우는 "사용함"으로 간주했습니다. 아직 갱신되지 않은 구버전 장비가 값을 받지 못했다는 이유로 취소 요청을 놓치면 안 되기 때문입니다. 기능을 끄는 조건은 명시적으로 꺼졌을 때로만 한정하는 편이 안전합니다.


6. 설치한 뒤를 위한 구조

장치 제어는 장비 안에서 끝내고, 서버는 기록과 설정을 맡습니다

장치 제어는 서버 없이도 끝까지 갑니다

수거 키오스크는 분쇄 장치를 서버를 거치지 않고 직접 제어합니다. 설치 장소마다 통신 품질이 다르고, 연결이 끊긴 순간에 분쇄가 멈추면 안 되기 때문입니다. 서버 연결이 끊겨도 투입과 분쇄는 계속 진행하고, 연결이 복구되면 결과를 다시 전송합니다.

서버가 맡는 것은 계정 확인과 결과 저장입니다. 포인트처럼 여러 화면에서 같은 값으로 보여야 하는 데이터는 서버가 확정한 값을 기준으로 삼습니다. 키오스크 화면의 숫자와 앱의 숫자가 다르면 이용자는 둘 다 믿지 않습니다.

모든 장비가 같은 빌드를 씁니다

200대가 넘는 장비에 장비마다 다른 버전을 설치하면 관리가 불가능해집니다. 수거 키오스크는 처음부터 두 가지를 조건으로 두었습니다. 모든 장비가 같은 소프트웨어를 돌린다는 것, 그리고 방문 없이 갱신한다는 것입니다.

장비마다 달라야 하는 값은 코드가 아니라 설정에 둡니다. 숙박 키오스크는 설치할 때 지점 코드를 한 번 입력하면 서버에서 인증 토큰을 받고, 이후에는 대기 화면에 들어올 때마다 서버에서 지점별 설정(화면 구성, 결제 방식)을 다시 읽습니다. 설정을 바꾸려고 장비를 방문할 일이 없습니다.

원격 갱신에는 시점이 중요합니다

숙박 키오스크는 앱이 켜질 때와 이후 60초마다 새 버전이 있는지 확인하고, 있으면 내려받아 바로 적용합니다. 반영이 빠른 대신, 누군가 결제하는 도중에 화면이 새로 고쳐질 수 있습니다. 그래서 배포는 이용자가 없는 시간대에 합니다.

갱신 방식은 반영 속도와 중단 위험 사이의 선택입니다. 수백 대에 문구 하나를 고쳐야 할 때는 빠른 반영이 유리하고, 결제가 얽힌 장비에서는 배포 시점을 함께 정해야 합니다.

관리자 진입로는 숨깁니다

관리자 화면은 일반 이용자에게 보이지 않아야 하고, 담당자는 도구 없이 들어갈 수 있어야 합니다. 시험장 키오스크는 화면의 로고를 짧은 시간 안에 연속으로 누른 뒤 비밀번호를 입력하면 관리자 화면이 열립니다. 숙박 키오스크도 특정 위치를 연속으로 누르는 방식으로 설정 화면에 들어갑니다. 화면에 "관리자" 버튼을 두지 않는 것만으로도 오조작이 크게 줄어듭니다.

기록은 장비 안에도 남깁니다

현장에서 생긴 문제는 그 자리에서 재현하기 어렵습니다. 나중에 확인할 수 있는 것은 기록뿐입니다. 장치 호출의 각 단계와 반환 값, 외부 시스템과 주고받은 요청, 결제 요청과 결과를 장비 안에 남깁니다. 결제 기록은 최근 건수만 보관하도록 상한을 두어 저장 공간이 차지 않게 합니다.

기록 항목은 어느 단계에서 멈췄는지를 구분할 수 있게 나눕니다. "신분 확인 실패"라는 한 줄보다, 장비 연결에 실패했는지, 판독에 실패했는지, 지원하지 않는 신분증 종류였는지가 남아 있어야 현장에 가지 않고 원인을 좁힐 수 있습니다.


7. 착수 전에 정해 둘 것

지금까지의 내용을 설계 단계에서 확인할 질문으로 정리했습니다.

개발 순서

  • 개발용 장치를 화면 개발보다 먼저 확보했는가
  • 장치만 단독으로 호출해 정상·실패·무응답을 확인했는가
  • 한 번의 동작에 걸리는 시간을 실측했는가

구조

  • 화면이 장치를 직접 호출하지 않고 정해진 통로로만 요청하는가
  • 장치 쪽 오류가 화면 전체를 종료시키지 않는가
  • 장치가 다른 모델로 바뀔 때 고쳐야 할 범위가 정해져 있는가

장치 신호

  • 모든 장치 호출에 제한 시간이 있는가
  • 진행 중인 요청이 있을 때 새 요청을 어떻게 처리하는가
  • 잠금이 풀리지 않는 경우에 대한 처리가 있는가
  • 중복 신호와 순서가 바뀐 신호를 걸러 내는가

화면 흐름

  • 현재 단계와 이동 규칙이 한 곳에 정의되어 있는가
  • 예외 상황이 정상 경로와 분리되어 있는가
  • 개인정보가 표시되는 화면에 자동 복귀 시간이 있는가

결제

  • 승인 요청 전에 단말 상태를 점검하는가
  • 승인은 됐지만 서버 등록이 실패한 경우의 처리가 정해져 있는가
  • 원격 취소 요청을 연결이 끊긴 상태에서도 받을 수 있는가
  • 취소 결과 보고가 실패하면 어디에 보관하고 언제 다시 보내는가

운영

  • 모든 장비가 같은 빌드를 쓰고 차이는 설정에 있는가
  • 원격 갱신이 이용 중인 화면을 끊지 않도록 시점을 정했는가
  • 서버 연결이 끊겨도 장치 제어가 끝까지 진행되는가
  • 기록에서 어느 단계가 실패했는지 구분되는가

마치며

키오스크 개발에서 화면은 결과물이고, 장치는 전제입니다. 장치가 얼마나 걸리는지, 어떻게 실패하는지, 응답이 없을 때 어떻게 되는지를 알아야 화면이 그 조건 위에서 설계됩니다.

세 프로젝트에서 반복해서 확인한 것은 한 가지입니다. 장치는 항상 응답한다는 가정을 버리면 구조가 정해집니다. 제한 시간을 걸고, 프로세스를 나누고, 애매한 결과는 사람에게 넘기고, 보내지 못한 결과는 보관했다가 다시 보냅니다. 화면 수가 다섯 개든 열 개든 이 부분의 작업량은 줄지 않습니다.

저희는 신분 확인 장비, 분쇄 장치, 결제 단말처럼 서로 다른 장치를 붙인 키오스크를 개발하고 운영해 왔습니다. 하드웨어 연동이 포함된 무인 시스템을 준비하고 계시다면 편하게 문의해 주세요.


함께 보면 좋은 글

  • 키오스크 프로젝트에서 개발보다 오래 걸리는 것들 — 무인화 시스템 구축 체크리스트
  • 외부 시스템 연동에서 장애가 생기는 자리 — 인터페이스 설계 원칙
  • 현장에 설치된 IoT 시스템을 운영한다는 것 — 단절·상태 불일치·원격 관리