ip cam 아키텍처 구상

최원상·2023년 3월 16일
0


알리 익스프레스에서 재밌어보이는 키트를 팔아서 해당 하드웨어를 기초로 움직이는 ip cam을 만들어 보기로 했다.
ip cam의 경우 esp32-cam 모듈 예제를 이용하며 간단하게 만들수 있고 이걸 이용하여 웹소켓 기반의 움직이는 ip cam을 제작하려고 한다.

아키택쳐 구상

  • 구동계 컨트롤러는 웹소켓 연결을 유지하며 컨트롤러 외 웹소켓이 연결되면 소켓서버는 구동계 컨트롤러로 cam 가동 명령
  • 구동계 컨트롤러와 cam 컨트롤러는 물리적으로 연결하며 구동계 컨트롤러에서 신호가 있을때만 cam 컨트롤러를 웹소켓에 연결
  • cam 스트리밍 데이터는 웹소켓 서버를 통해 외부 디바이스(피씨 또는 모바일)로 전달
  • 웹 페이지 통해 인증 받은 디바이스만 웹 소켓에 연결 할 수 있도록 구성
  • 추후 보안 강화를 위해 서버를 내부망에 두고 제로티어 같은 vpn 이용 하도록 수정 예정

test

  • 웹소켓 서버를 따로 두고 스트리밍을 해보았으나 스트리밍 지연이 1~2초로 실시간으로 구동계 컨트롤하기 힘들어 보여 아키텍처 수정이 필요해보임

test 해볼 목록

1. 메세지 전송전 조건문 삭제 및 서버 2개 뛰우기

2. 아두이노에 따로 웹소켓 클라이언트는 두어 esp32-cam 부하 저감

3. 언어 변경 golang or rust

4. esp32-cam에서 직접 소켓서버를 뛰우고 포트포워딩

'use strict'
const wsModule = require('ws');



class Websocket {
    
    constructor() {
        this.ipcam;
        this.mon;
    }

    createServer(HTTPServer){
        console.log(`ws server on`);
  
        const wsServer = new wsModule.Server( 
            {
                server: HTTPServer, // WebSocket서버에 연결할 HTTP서버를 지정한다.
               
            }
        );
        
        wsServer.on('connection', async (ws, request)=> {

            const ip = request.headers['x-forwarded-for'] || request.connection.remoteAddress;
            console.log(`새로운 클라이언트[${ip}] 접속`);
            const conAuth = request.headers['sec-websocket-protocol'];
            const conAuthArr = conAuth.split('_');
            if(conAuthArr[0]=="mon" && conAuthArr[1] == "2938" && this.mon ===undefined){
                this.mon = ws;
                console.log(`mon up`);
                ws.on('message', (msg)=>{
                    if(this.ipcam !==undefined){
                        console.log(Date.now()+`ipcam send : ` + msg);
                        this.ipcam.send(msg);
                    }
                })
            }else if(conAuthArr[0]=="ipcam" && this.ipcam ===undefined){
                this.ipcam = ws; 
                console.log(`ipcam up`);
                ws.on('message', (msg)=>{
                    if(this.mon !==undefined){
                        this.mon.send(msg);
                    }
                })
            }else{
                ws.close();
            }
            

            // 2) 클라이언트에게 메시지 전송
            if(ws.readyState === ws.OPEN){ // 연결 여부 체크
           
            }
            
          
            
            // 4) 에러 처러
            ws.on('error', (error)=>{
                console.log(`클라이언트[${ip}] 연결 에러발생 : ${error}`);
            })
            
            // 5) 연결 종료 이벤트 처리
            ws.on('close', ()=>{
                console.log(`클라이언트[${ip}] 웹소켓 연결 종료`);
                if(conAuthArr[0]=="mon"){
                    this.mon = undefined;                
                    console.log(`mon die`);
                }else if(conAuthArr[0]=="ipcam"){
                    this.ipcam = undefined;                
                    console.log(`ipcam die`);
                }
            })
         
        });
    }
}
module.exports=Websocket;
profile
한 줄로는 안되지

0개의 댓글