본문 바로가기

Spring

[Spring] 화상 채팅 구현하기 (ZEGOCLOUD API 활용 O, WebRTC X, Feat.Thymeleaf)

728x90
반응형
SMALL

ZEGOCLOUD

 

Voice & Video Chat API for Real-Time Interaction- ZEGOCLOUD

High availability and rapid scalability 99.99% of uptime and the capability to scale out in seconds to handle tens of millions of concurrent stream subscriptions. Rich developer resources Useful code snippets, open-source sample projects, and best practice

www.zegocloud.com

  • 해당 사이트에서 화상 채팅, 라이브 스트림 등을 지원해준다.
  • 우선 회원가입을 한다 (본인은 구글계정을 사용)
  • 그러면 dashboard로 이동하게 된다.

 

Dashboard 화면

  • 여기에서 Create Your Project 선택

 

 

어떤 API를 사용하고 싶은지 선택할 수 있음

  • 프로젝트를 진행하면서 나는 Voice&Voice Call 만 선택했었다.
  • 밑으로 내려서 Next 버튼 누르기

 

프로젝트 이름을 작성하고 2 ways to started를 확인

  • 프로젝트를 진행하면서 나는 UIKits를 사용하였다.
  • 더 간단하고 이미 만들어준걸 배포해주는 느낌 이었다.

로딩창 -- 만들어지고있다고 함

  • 위 화면이 끝나면 FrameWork Selection 이 나타난다.
  • 어떤 프레임 워크에서 사용할 화샅 채팅에 대한 세팅을 도와준다

For Web을 선택
1대 1일때, Group call일때 의 화면 세팅을 할 수 있다.

  • Button 밑에있는 옵션을 끄면 화면 하단에 있는 버튼들을 없애고 생기게 할 수 있다.
  • Module에 있는 옵션은 채팅하는 기능과 누가 들어와았는지에 대한 내용
  • Advanced Configuration 은 처음 들어올때 마이크가 켜져있고, 카메라가 켜져있고에 대한 내용
  • 맨 밑에이있는 Save & Start to Integrate 를 선택

 

  • Get the config file & Integrate를 선택

 

해당 화면이 보여진다.

  • Download HTML file을 선택하면 해당 코드가 들어간 HTML 파일을 다운 받을 수 있다.
<html>

<head>
    <style>
        #root {
            width: 100vw;
            height: 100vh;
            }
    </style>
</head>


<body>
    <div id="root"></div>
</body>
<script src="https://unpkg.com/@zegocloud/zego-uikit-prebuilt/zego-uikit-prebuilt.js"></script>
<script>
window.onload = function () {
    function getUrlParams(url) {
        let urlStr = url.split('?')[1];
        const urlSearchParams = new URLSearchParams(urlStr);
        const result = Object.fromEntries(urlSearchParams.entries());
        return result;
    }


        // Generate a Token by calling a method.
        // @param 1: appID
        // @param 2: serverSecret
        // @param 3: Room ID
        // @param 4: User ID
        // @param 5: Username
    const roomID = getUrlParams(window.location.href)['roomID'] || (Math.floor(Math.random() * 10000) + "");
    const userID = Math.floor(Math.random() * 10000) + "";
    const userName = "userName" + userID;
    const appID = /*들어가 있음*/;
    const serverSecret = /*들어가 있음*/;
    const kitToken = ZegoUIKitPrebuilt.generateKitTokenForTest(appID, serverSecret, roomID, userID, userName);

    
        const zp = ZegoUIKitPrebuilt.create(kitToken);
        zp.joinRoom({
            container: document.querySelector("#root"),
            sharedLinks: [{
                name: 'Personal link',
                url: window.location.protocol + '//' + window.location.host  + window.location.pathname + '?roomID=' + roomID,
            }],
            scenario: {
                mode: ZegoUIKitPrebuilt.VideoConference,
            },
                
            turnOnMicrophoneWhenJoining: true,
            turnOnCameraWhenJoining: true,
            showMyCameraToggleButton: true,
            showMyMicrophoneToggleButton: true,
            showAudioVideoSettingsButton: true,
            showScreenSharingButton: true,
            showTextChat: true,
            showUserList: true,
            maxUsers: 50,
            layout: "Auto",
            showLayoutButton: true,
         
            });
}
</script>

</html>

 

  • 위 코드의 설명을 보면 URL을 통해서 roomID, userID 등이 지정 될 수 있고 만약 없다면 Math.random을 통해 무작위로 지어주게 된다.
  • 실행 시켰을 때 영상

 

시연 영상


Spring에 접목 시키기 with Thymeleaf

 

Controller

@GetMapping("/videocall")
public String videocall(Model model, @AuthenticationPrincipal PrincipalDetails userDetails){
    if(userDetails != null){
        model.addAttribute("user", userDetails.getUser());
        model.addAttribute("appID", appID);
        model.addAttribute("serverSecret", serverSecret);
    }else{
        return "user/login";
    }

    return "user/videocall";
}

 

  • 해당 프로젝트에서의 Controller에 있는 videocall.html 에 접근 할 수 있도록 활용

 

HTML (View)

<html lang="ko" xmlns:th="http://www.thymeleaf.org">

<head>
    <title>VIDEOCALL</title>
    <style>
        #root {
            width: 100vw;
            height: 100vh;
            }
    </style>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js"></script>
    <script src="https://use.fontawesome.com/releases/v6.3.0/js/all.js" crossorigin="anonymous"></script>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootswatch@5.3.2/dist/sketchy/bootstrap.min.css">
</head>


<body class="sb-nav-fixed">

    <th:block th:insert="~{common/menubar::menubar}"></th:block>
    <div id="layoutSidenav">
        <th:block th:insert="~{common/sidebar::sidebar}"></th:block>

    <!--오른쪽 메뉴바가 아닌 부분에 대한 내용-->
    <div id="layoutSidenav_content">

        <div id="root"></div>

        <th:block th:insert="~{common/footer::footer}"></th:block>
    </div>
    </div>
</body>

<script src="https://unpkg.com/@zegocloud/zego-uikit-prebuilt/zego-uikit-prebuilt.js"></script>
<script th:inline="javascript">
window.onload = function () {
    function getUrlParams(url) {
        let urlStr = url.split('?')[1];
        const urlSearchParams = new URLSearchParams(urlStr);
        const result = Object.fromEntries(urlSearchParams.entries());
        return result;
    }


        // Generate a Token by calling a method.
        // @param 1: appID
        // @param 2: serverSecret
        // @param 3: Room ID
        // @param 4: User ID
        // @param 5: Username
    const user = [[${user}]] || null;
    const roomID = getUrlParams(window.location.href)['roomID'] || user.id + "";
    const userID = user.id + "" || null;
    const userName = user.name || null;//"userName" + userID;
    const appID = [[${appID}]];
    const serverSecret = [[${serverSecret}]];
    const kitToken = ZegoUIKitPrebuilt.generateKitTokenForTest(appID, serverSecret, roomID, userID, userName);

    
        const zp = ZegoUIKitPrebuilt.create(kitToken);
        zp.joinRoom({
            container: document.querySelector("#root"),
            sharedLinks: [{
                name: 'Share this link!!',
                url: window.location.protocol + '//' + window.location.host  + window.location.pathname + '?roomID=' + roomID,
            }],
            scenario: {
                mode: ZegoUIKitPrebuilt.VideoConference,
            },
            turnOnMicrophoneWhenJoining: false,
            turnOnCameraWhenJoining: false,
            showMyCameraToggleButton: true,
            showMyMicrophoneToggleButton: true,
            showAudioVideoSettingsButton: true,
            showScreenSharingButton: true,
            showTextChat: true,
            showUserList: true,
            maxUsers: 5,
            layout: "Auto",
            showLayoutButton: false,
        });
}
</script>
<script>
    $(document).ready(function () {
        $('.VsTVUAD89KWleD0YRVsD').click(function (){
           window.open(window.location.protocol + '//' + window.location.host  + window.location.pathname + '?roomID=' + roomID, "_blank");
        });

    });
</script>
</html>
  • Thymeleaf문법을 사용해서 로그인 되어있는 유저의 이름과 필요한 API의 Key값을 가져오게 했음
  • 밑에는 위 코드가 실행되고 있는 실제 프로젝트에서의 동작 영상

 

실제 프로젝트에서 사용된 ZEGOCLOUD API 사용 사례

 

 

 

해당 API는 localhost 실행 되어있지 않거나 도메인 이름으로 배포 되어 사용 할때는 https로 되어있어야 한다.

 

https://jk25.tistory.com/186

 

[AWS] Route53 도메인 https 로 배포하기 (Feat. CloudFlare)

프로젝트를 진행하다가 사용한 API가 localhost 로는 지원이 가능 하나 도메인으로 배포했을 시 https가 아니면 사용 할 수 없었다. (ZEGOCLOUD) 따라서 빠르게 https 를 설정 하는 방법에 대해서 알아보았

jk25.tistory.com

 

728x90
반응형
LIST