1. Screen Sharing - SocketIO Setting

배고픈 징징이 ㅣ 2024. 8. 9. 13:15

1. 설명

화면 공유 기술이 필요했다.

처음에는 WebRTC를 사용하려 했지만, UDP를 사용하는 WebRTC의 특성상 TURN Server가 필요했다.

이 프로젝트에서는 TURN Server를 제공할 여유가 없었다.

그래서 TURN Server가 필요없는 TCP 통신으로 구현을 구상하였다.

TCP 통신을 사용하는 Websocket과 Socket.io를 고민하다가 Socket.io로 개발하기로 했다.

이에 이 글에서는 WebRTC 없이 화면을 공유하는 방법에 대해 포스팅하려 한다.

이 글은 단순히 Socket 통신만을 구현한 코드이고, 다음 글에서 화면 공유기능이 추가된 코드를 포스팅하겠다.

이제 테스트까지 끝마친 코드를 기준으로 설명한다.

 

서버는 NestJS를 사용했다.

 

2. Socket.io Setting

먼저 가장 기초가되는 Socket.io를 세팅해야 한다.

참고로 필자는 무슨 이유에서인지.. import문이 자동으로 생성되지 않아서 import {} from "" 구문을 다 직접 적어야 사용이 가능했다.

from 절에서 자동완성 기능으로 라이브러리만 정상적으로 노출된다면, 사용하는데 아무 문제가 없는것 같다.

 

2.1 Client

먼저 클라이언트부터 작성하겠다.

클라이언트에서 사용할 socketio부터 설치한다.

 

npm i socket.io-client

 

그리고 설치한 socketio의 socket.io-client를 사용하여 중계 서버와 연결한다.

아래에서 사용한 3080 포트는 중계 서버의 포트이다.

io 메소드에서 많은 옵션 값들을 추가해 줄 수 있지만, 초기 세팅 단계에서는 복잡해지기만 하는 이유로 사용하지 않았다.

 

import { io } from "socket.io-client";

export var ToolSharing = {
    sharing : (function(){
        const socket = io("http://localhost:3080", {transports : ["websocket"]});
        
        // 소켓이 연결되면 자동으로 connect로 연결된다.
        socket.on('connect', () => {
            //message라는 이름으로 서버에 문자열 전송
            socket.emit('massage', 'Hello, server!');
            
            //서버에서 보내온 message라는 이름의 데이터 출력
            socket.on("message", message => {
                console.log("message", message);
            });
        });
    })()
}

 

2.2 Server

먼저 필요한 의존성 주입을 한다.

의존성 주입 전에 참고 사항은 Socket과 관련된 애들을 설치할 때, socket.io를 제외한 두개는 common의 버전과 일치 시켜서 설치를 해야 오류가 없었다.

자신의 common 버전을 확인하고 진행하자.

아래는 필자의 package.json 일부분이다.

"dependencies": {
    "@nestjs/common": "^8.0.6",
    ...
    "@nestjs/platform-socket.io": "^8.4.7",
    "@nestjs/websockets": "^8.4.7",
    "socket.io": "^4.7.5"
}

 

설치시에 버전을 맞추지 않으면 오류가 발생하는데,

해결 방법으로 --force와 --legacy-peer-deps 를 사용하라고 로그에 적혀있는데,

필자가 잘 못 설치한 것인지 잘 되지 않았다.

그래서 버전을 맞추는걸 추천한다.

npm i @nestjs/websockets@8
npm i @nestjs/platform-socket.io@8
npm i socket.io

 

이제 개발 준비는 끝났다.

서버 쪽에서 시간이 오래 걸렸는데, 어노테이션이나 메소드들이 자동 완성이 되지않는다고 놀라지 말고

직접 import 문을 적어주면 잘 돌아간다.

그대신 from 절은 자동 완성이 되어야 한다.

 

먼저 핵심이 되는 Gateway를 먼저 작성한다.

afterInit의 경우 초기화 후에 실행이 된다는데, 호출이 되지도 않고 정확한 사용법을 아직 못찾았다.

afterInit , handleConnection, handleDisconnect은 상속받은 아이들이다.

implements로 상속 받는 이상 무조건 작성해줘야 한다.

import { MessageBody, OnGatewayConnection, OnGatewayDisconnect, OnGatewayInit, SubscribeMessage, WebSocketGateway, WebSocketServer } from "@nestjs/websockets"
import { Server } from "socket.io"

//WebSocketGateway에서는 Port, cors 등등 옵션 값을 줄 수 있는데,
//이또한 초기 세팅에서는 굳이 필요하지 않기 때문에, 간결한 코드를 위해 여기서는 작성하지 않았다.
@WebSocketGateway()
export class SharingGateway implements OnGatewayConnection, OnGatewayInit, OnGatewayDisconnect{
    @WebSocketServer() server : Server;

    //초기화 후에 가장 먼저 실행되는 메소드
    afterInit(server : Server){
        console.log("afterInit", server , this.server);
    }

    //connection이 이루어지면 호출되는 메소드
    handleConnection(client: any, ...args: any[]) {
        console.log("connection");
    } 

    //connection이 끊어지면 호출되는 메소드
    handleDisconnect(client: any) {
        console.log("disconnection");
    }

    //nessage라는 이름의 데이터를 받아서 서버에 message라는 이름으로 뿌려주는 메소드
    @SubscribeMessage("massage")
    handleMessage(@MessageBody() body){
        this.server.emit("message", "돌려줄게");
    }
}

 

Gateway를 작성했으면 이제 Gateway를 app이 사용하게 세팅을 해줘야 한다.

먼저 Gateway를 포함하는 Module을 작성한다.

따로 Gateway Module 없이 바로 App Module에 추가해서도 사용이 가능한데,

필자는 따로 Module을 작성하였다.

import { Module } from "@nestjs/common";
import { SharingGateway } from "./sharing.gateway";

@Module({
    providers: [SharingGateway]
})
export class SharingModule {}

 

Module을 작성했으면, 이제 해당 Module을 app.modules에  import로 추가하여 사용될 수 있게 한다.

...
import { SharingModule } from './sharing/sharing.module';
...

@Module({
  imports: [
    ...
    SharingModule
  ],
  ...
})
export class AppModule { }

 

여기까지 진행했다면, 서버와 클라이언트의 로그를 볼 수 있을 것이다.

이제 통신을 위한 기본 세팅이 끝났다.

본격적인 화면 공유는 다음 글에서 이어가도록 하겠다.

 

* 참고

main.ts에서 app 어뎁터를 사용한다는 글들도 있는데, 아직까지는 굳이 필요하지 않았다.

또한 서버와 Gateway의 포트가 겹치면 문제가 생긴다는 글들도 있었지만, 같은 포트를 사용하여도 문제가 없었다.

 

반응형

'NodeJS' 카테고리의 다른 글

3.Screen Sharing - Mouse Event  (0) 2024.08.12
2.Screen Sharing - Sharing  (0) 2024.08.09
NextJs  (0) 2024.07.23
Express & NestJS  (0) 2024.07.16
VSCode에서 NestJs 디버깅  (0) 2024.07.04