[사물 인터넷 네트워크와 서비스 구축 강좌] #4-4 센서장치에 웹 소켓 활용하기

 

강좌 목차 보기

  • 현재 강좌 ==> [사물 인터넷 네트워크와 서비스 구축 강좌] #4-4 센서장치에 웹 소켓 활용하기

 

 

이전 실습 예제에서는 HTTP client 가 주기적으로 서버에 HTTP 요청을 보내서 데이터를 가져왔습니다. 물론 이 방식이 일반적인 웹 사용법이긴 하지만 특정 서비스에는 적합하지 않은 측면이 있습니다. 예를들어 특정 웹 페이지에 채팅 기능을 넣는다고 생각해보세요. 실시간으로 채팅 메시지가 보여지도록 하려면 브라우는 매우 빠르게 그리고 끊임없이 HTTP request 를 보내야 할 것입니다. 채팅 같은 기능에는 항상 서버-클라이언트가 백그라운드로 연결된 상태를 유지하면서 실시간-양방향으로 자유롭게 데이터를 주고 받는 방식이 필요합니다.

Web Socket 이 이런 자유로운 통신 방식을 제공해줍니다. HTML5에 포함된 Web Socket은 웹 서버와 클라이언트(브라우저의 JavaScript 등) 간 소켓 연결을 유지하게 해 줌으로써, 지속적인 양방향 데이터 전송을 할 수 있습니다. 다만, 이 기능을 사용하기 위해서는 비교적 최신의 브라우저를 사용해야 하는 제약이 있습니다. 그리고 서버에는 WebSocket 통신을 위한 준비가 되어 있어야 합니다. 보통 웹 소켓은 브라우저에서 많이 사용하지만 웹 소켓이 특정 플랫폼에 종속된 것은 아닙니다.

이번 파트에서는 ESP32 모듈을 이용해서 웹 소켓 통신을 구현하는 방법을 다룹니다.

 

 

웹 소켓 서버 구현

 

ESP32 모듈을 웹 소켓 서버로 구현해 보도록 하겠습니다. 그리고 라즈베리파에에 파이썬으로 웹 소켓 클라이언트를 구현할 것입니다. 웹 소켓이 연결되면 라즈베리파이의 웹 소켓 클라이언트에서 메시지를 보냅니다. 웹 소켓 서버는 받은 메시지를 다시 클라이언트에게 되돌려 줄 것입니다.

 

ESP32 모듈에 웹 소켓 기능을 넣기 위해 라이브러리 설치가 필요합니다. 아래 링크에서 라이브러리 파일을 받으세요.

 

다운받은 소스를 아두이노 라이브러리 폴더에 복사합니다. 아두이노 라이브러리 폴더의 경로는 다음과 같습니다. 라이브러리 파일들이 담긴 폴더를 붙여넣기 할 때 라이브러리 폴더의 이름을 WebSocketServer로 만드세요.

  • C:\사용자\사용자명\문서\Arduino\libraries

 

이 라이브러리를 그냥 사용할 경우  기존의 MD5 관련 함수와 충돌이 발생합니다. WebSocketServer 라이브러리 폴더 내 MD5.c 와 MD5.h 파일에서 다음 문자열을 찾아서 모두 치환해 주면됩니다.

  • MD5Init →MD5Init_XXX
  • MD5Update →MD5Update_XXX
  • MD5Final →MD5Final_XXX

_XXX 는 원하는대로 지정하면 됩니다.

 

이제 ESP32 용 웹 소켓 서버 예제를 올려보겠습니다. 아래 링크에서 스케치를 받을 수 있습니다.

 

ESP32 서버용 코드를 컴파일 후 업로드하면 ESP32 가 서버로 동작하기 시작합니다. ESP32 모듈의 IP 주소를 꼭 기억해두세요!!

 

ESP32 모듈에 웹 소켓 서버 구현은 끝났으니 라즈베리파이에 웹 소켓 클라이언트를 구현하겠습니다. 파이썬과 websocket-client 모듈을 이용합니다.

라즈베리파이에 접속 후 PIP 를 이용해 websocket-client 를 설치합니다.

  • sudo pip3 install websocket-client

 

아래 링크에 웹 소켓 클라이언트를 구현한 파이썬 코드가 있습니다.

 

소스코드에서 ESP32 모듈의 IP 주소를 넣어주세요.

 

파이썬으로 작선된 웹 소켓 클라이언트 코드는 단순합니다. 특정 IP 로 웹 소켓 접속을 한 후, 1초 간격으로 메시지를 200번 보냅니다. 메시지 전송할 때는 ws.send() 를 이용합니다. 메시지 수신은 ws.recv() 를 사용하면 됩니다.

 

ESP32 웹소켓 서버가 구동되고 있는 상태에서 파이썬 코드를 실행하면 메세지가 오고가는 것을 확인할 수 있습니다.

 

ESP32 모듈에 업로드 한 소스코드를 살펴보겠습니다. 먼저 setup() 함수를 살펴보면…

공유기에 연결하고, 웹 서버를 시작했습니다.

 

웹 서버로 HTTP request 요청이 오면 그 안에 웹 소켓 연결을 요청하는 정보가 있습니다. 이때 웹 소켓 연결을 위한 handshake 과정을 거치면 연결됩니다. loop() 안에서 순차적으로 이 작업을 처리해줍니다.

 

이 코드는 간단하게 웹 소켓 연결을 구현해주고 있지만 제약사항이 하나 있습니다. 웹 소켓 연결이 되면, 연결이 종료될 때 까지 다른 웹 소켓 연결요청을 처리할 수가 없습니다. 만약 여러개의 웹 소켓 연결을 동시에 처리하고 싶다면 몇 가지 수정을 해줘야 합니다.

기존에 사용했던 WebSocketServer 라이브러리를 삭제하고 대신 다중 웹 소켓 접속을 지원하는 라이브러리를 설치하세요.

 

그리고 아래 코드를 사용하면 다중 웹 소켓 서버를 만들 수 있습니다. 라즈베리파이에 여러개의 터미널로 접속 한 뒤, 파이썬 웹 소켓 클라이언트 코드를 여러개 실행시켜 확인해보세요.

 

 

웹 소켓 클라이언트 구현

 

이번에는 ESP32 모듈을 웹 소켓 클라이언트로 사용해 보겠습니다. 외부에 우리가 다룰 수 있는 웹 서버가 존재한다면 이렇게 구현하는 것이 더 효율적이겠죠.

 

먼저 라즈베리파이에 웹 소켓 서버를 구동시키겠습니다. 라즈베리파이에 접속해서 websockets 파이썬 모듈을 설치해야 합니다.

  • sudo pip3 install websockets

 

설치가 완료되면 아래 코드를 구동시켜보세요.

websocket.server() 함수 호출해서 웹 소켓 서버를 구동시킵니다. 이때 사용할 웹 서버 포트번호와 IP address, 메시지를 받았을 때 실행할 콜백 함수를 함께 전달합니다.

파이썬 코드를 실행시키면 라즈베리파이는 웹 소켓 접속이 있을때까지 대기합니다.

  • sudo python webSocketServer.py

이때 표시되는 서버 주소를 기억해주세요.

 

이제 ESP32 모듈에 웹 소켓 클라이언트를 구현하면 됩니다. 아래 링크의 스케치를 사용하세요.

 

소스코드 상단의 설정 값을 자신의 환경에 맞게 바꿔줘야 합니다.

공유기 SSID와 비번을 지정해주고, 웹 소켓 서버 주소를 넣어주세요.

 

이제 ESP32 에 업로드하고 시리얼 모니터를 실행해서 통신 상태를 확인하면 됩니다.

두 장치가 메시지 카운트를 주고 받으면 성공입니다!!

 

ESP32 모듈에 올린 소스코드를 확인해 보겠습니다. setup() 함수에서 중요한 부분만 추려보면 아래와 같습니다.

일단 공유기에 연결이 되면 client.connect() 를 통해 라즈베리파이 서버에 연결합니다. 그리고 웹 소켓 연결을 위한 handshake 를 실행합니다. 이 과정이 성공하면 ESP32 와 라즈베리파이는 서로 실시간-양방향 통신이 가능해집니다.

 

loop() 함수에는 데이터 전송과 수신 코드만 있습니다.

 

 

활용

 

ESP32 모듈을 이용해서 센서장치를 만들 때, 웹 소켓을 활용하면 서버와 실시간으로 데이터를 주고 받을 수 있습니다. 그럼 서버에서는 실시간 센서 모니터링이 가능하겠죠.

만약 굉장히 많은 수의 센서가 데이터를 전송해야 하는 상황이라면 이런 웹 소켓 방식은 서버측에 버거울 수도 있습니다. 하지만 비교적 적은 수의 센서가 실시간 모니터링이 필요한 데이터를 전송하는 환경이라면 웹 소켓은 한번 고려해 볼만 한 옵션입니다.

 

 

 

참고자료

 

 

주의!!! [사물 인터넷 네트워크와 서비스 구축 강좌] 시리즈 관련 문서들은 무단으로 내용의 일부 또는 전체를 게시하여서는 안됩니다. 계속 내용이 업데이트 되는 문서이며, 문서에 인용된 자료의 경우 원작자의 라이센스 문제가 있을 수 있습니다.

 

강좌 목차 보기

  • 현재 강좌 ==> [사물 인터넷 네트워크와 서비스 구축 강좌] #4-4 센서장치에 웹 소켓 활용하기

 

Post Author: TORTUGA

TORTUGA
궁금하신 점은 새로 개편한 홈페이지의 QnA 게시판을 이용해주세요!!!!!!! http://www.hardcopyworld.com/gnuboard5/bbs/board.php?bo_table=qna

댓글 남기기

이메일은 공개되지 않습니다.