본문 바로가기
SW Jungle [예림]/Project

[Project 나만의 무기] - 회고 02.14~17 D-26~중간발표

by novxerim 2022. 12. 30.

https://velog.io/@yerimii11/Project-%EB%82%98%EB%A7%8C%EC%9D%98-%EB%AC%B4%EA%B8%B0-%ED%9A%8C%EA%B3%A0-02.1417-D-26%EC%A4%91%EA%B0%84%EB%B0%9C%ED%91%9C 2022년 2월 17일에 작성된 게시글 아카이브입니다.  (사유: 블로그이전)

 

[Project 나만의 무기] - 회고 02.14~17 D-26~중간발표

2\. 기술적 고민
백엔드 팀 공부 예정발표 후 포스터 세션 이어지니까, 피피티에 팀 소개 페이지 + 얼굴 사진 첨부할 것!폰트 크기 너무 작게 하면 X, 글 그대로 줄줄 읽지 말 것.3.10 실제 발표때

velog.io


📖 02.14 월요일

1. 공부 진행 상황

  • 오늘 할 일
    • 캐릭터 좌표 server.js로 이동 (socket코드)
      • 화상통화 코드 (overworld.js) - WebRTC / Mesh
        1. N:M 코드 테스트
          → test따로 하려다가, 시간 관계 상 바로 프론트 코드에 넣어 바로바로 수정하며 테스트 진행함.
        2. overworld.js - N:M connection 코드 합치기 (union-find or stack)
          → 알고리즘X, 스택 사용.
    • Room 나누기
  • 프론트쪽에서 작업하던 서버 코드와 우리가 구현해야 할 기능 코드와 합쳐야한다. → 합치고나서 캐릭터 움직임 버벅임 발생
  • Algorithm

2. 기술적 고민

  • 캐릭터간 거리가 가까워질 때 비디오콜을 누가 먼저 실행시킬 것인가? (2.14)
    문제 :
    • 캐릭터간 거리가 가까워질 때 비디오콜을 누가 먼저 실행시킬 것인가?
    고민과정 :
    • 1. room 생성 순서
      • 로비(방)에 입장시 소켓Id마다 Index를 주어서, (오름차순) 인덱스 숫자가 낮은 유저가 방을 생성한다
      • 혹은 소켓Id를 문자열 비교를 통해 순서를 나눈다.
      • 유저1, 2가 room을 생성 중 유저3이 합류했을 때
        • sync로 순서를 나누어 해결할 수 있지 않을까?
        • 혹은 세마포어(lock)를 활용해 같은 범위에 있는 유저 중 누군가가 room이 생성중일 때 다른 유저가 room을 만들 수 없도록
    • 2. connection 순서
      • 처음 로비(방)에 입장하면서 모든 사람들과 connection을 만들어 놓고 캠 화면은 띄우지 않는 방식
      • connection을 만드는 것 자체가 아니라, 캠 화면을 출력하는 것이 큰 부하를 주는 것이라면
        connection을 미리 전부 해놓고 거리가 가까워지는 사람들끼리만 캠 화면을 띄우면 좀 나을지?
      • Mesh 방식이 유저가 5명 이상부터 부하가 크게 걸리기 시작하므로 제약이 있을 듯 하다
        • 예를 들면, 로비의 모든 사람들이 모이는 경우 → 최대 5명까지만 연결되게 해야한다
          • 10명이면 5명-5명 2그룹으로.
    • 대안 :
    • 동시에 거리가 가까워진 유저가 서로 offer 를 보내기 위해 call-answer를 주고 받을 때도 누가 먼저 전달할 것인지 순서를 정해야 한다.
    • 프론트엔드에서 거리가 가까운 유저들끼리만 그룹으로 묶어서 소켓ID를 백엔드(서버)로 보내줄 것이다.
    • 그리고나서 서버에서 거리가 가까워진 유저들의 소켓ID를 스택에 넣고, Union-Find 알고리즘을 적용해 정렬(?) 한 후 다시 프론트로 보내준다.
        group = [
        	{ caller : "-----socket ID-----",
        		callee : "-----socket ID-----"
        	}, 
        	{
        		caller : "-----socket ID-----",
        		callee : "-----socket ID-----"
        	},
        	...
        
        ]
  1. 2명이 가까워질 때
    • 클라이언트에서 받은 group을 이용해 유저들의 소켓ID를 스택에 넣고, 첫 번째 pop으로 나온 소켓ID를 새로운 방을 하나 생성해서 room에 넣는다. 그 후 남은 유저를 room에 넣는다. (두 번째 유저가 room에 들어올 때, 유저1과 유저2의 커넥션이 형성된다)
      • pop을 하는 경우, 먼저 room을 생성하게 되는 유저의 명확한 기준은 없다.
  2. 3명이 가까워질 때
    • 유저1, 2가 만나면서 먼저 Room이 생성될 것이고, 유저3은 이미 만들어진 유저1, 2의 방에 들어간다. Union-Find로 유저 1과 유저2가 그룹이라는 것을 파악하면, 유저3을 그룹에 넣는다.
  3. 그 외 - 두 그룹이 가까워질 때
    • 일단 위에 해보기
  • 가까워지는 캐릭터의 좌표를 서버에서 받음
  • N:M이 되게하는 핵심코드를 찾아서 우리 코드에서 N:M이 되게 하기

3. 성찰

  • 하다보니 프론트쪽 작업이 많아져서 함께 페어프로그래밍 했다.
  • 비디오 연결 시 어떤 코드가 추가된거지???? 보고 가자

📖 02.15 화요일

1. 공부 진행 상황

  • 페어프로그래밍
    • 프론트와 코드 합치기 (서버코드, 다대다 영상스트림 재생)
    • offer-answer-icecandidate 코드 추가 후 잘 작동하는지 체크
      • 기존에는 1:1이라서 offer를 to로 보낼 때 room 안의 모든 사람에게 보내도 상관 없었는데, 이번에는 socketId list를 가져와서 그 sid를 가지고 있는 사람에게만 보내야했다 (room안의 group에 해당하는 사람에게)
      • 달라진 점 : signal을 통해 offer, answer을 주고 받는 대상이 개인이 아니라 그룹에 속한 개인이었다.
    • 유저간 거리에 따른 방 생성
      • room1, room2 두 개라 헷갈려서 room2 → group으로 이름 수정
      • joinGroup, makeGroup 함수 추가
            //when caller make the room
            function makeGroup(groupName, socket, nickname) {
              initGroupObj = {
                groupName,
                currentNum: 0,
                users: {
                  socketId: socket.id,
                  nickname
                },
              };
              groupObjArr.push(initGroupObj);
              // return targetGroupObj;
              socket.join(groupName);
              socket.emit("accept_join", targetGroupObj.users);
            }
            //when callee join the room
            function joinGroup(groupName, socket) {
              for (let i = 0; i < groupObjArr.length; ++i) {
                if (groupObjArr[i].groupName === groupName) {
                  // Reject join the room
                  if (groupObjArr[i].currentNum >= MAXIMUM) {
                    socket.emit("reject_join");
                    return;
                  }
                  //Join the room
                  targetGroupObj.users.push({
                    socketId: socket.id,
                    nickname,
                  });
                  ++targetGroupObj.currentNum;
            
                  socket.join(groupName);
                  socket.emit("accept_join", targetGroupObj.users);
                }
              }
            }
  • 채팅기능 추가 → 프론트에서 사이드바 UI와 합칠 예정
  • 거리가 가까워지면 영상통화 실행이 안되고 터짐. 체크 필요 → 해당 기능 코드만 수정하고 돌렸을 때는 잘 작동했으나 다른 기능 코드와 합치니 다시 작동 안됨
  • 거리가 멀어질 때 disconnect(leave_Group) 함수 만들기
    • server
        // app.js (server)
        
        socket.on("leave_Group", (sId) => {
            console.log("________ㅠㅠ 멀어졌다..____________", sId) // player.id로 groupObjArr에서 roomName찾기
            for (let i = 0; i < groupObjArr.length; ++i) {
              // console.log(groupObjArr[i].groupName)
        
              for (let j = 0; j < groupObjArr[i].users.length; ++j) {
                console.log(groupObjArr[i].users[j].socketId)
        
                // 거리가 멀어질 player의 sid로 화상통화 그룹 정보에 저장된 동일한 sid를 찾아서 그룹에서 삭제해준다
                if (sId === groupObjArr[i].users[j].socketId) {
                  console.log('***', groupObjArr[i].users)
                  socket.leave(groupObjArr[i].groupName) // socket Room 에서 삭제
                  groupObjArr[i].users.splice(j,1) // 우리가 따로 저장했던 배열에서도 삭제
                  console.log('*지웠나 체크*', groupObjArr[i].users)
                }
            }
          }
            console.log("____________leave_group____________")
            
            // unGroup(groupName, socket, nickname);
          });
        });
- client
    
        // Overworld.js 캐릭터 좌표 움직임 함수 내에 작성
        
        if (Math.abs(player.x - object.x) > 96 || Math.abs(player.y - object.y) > 128) {
                      console.log("멀어짐")
                      // console.log(socket)
                      player.isUserCalling = false;
                      object.isUserCalling = false;
                      // console.log(player, object);
                      socket.emit("leave_Group", object.id);
                      // socket.emit("disconnected");
        
                    }

  • Algorithm X

2. 기술적 고민

  • 소켓에 그룹네임을 추가하자
  • disconnect와, 다자간 영상통화/채팅를 각각 구현했는데 두 코드를 합치려하니 한 기능만 돌아가고 한 기능은 안된다. 계속 GetTracks가 안되고 있다는데, 원인을 몇 시간 째 못 찾고있다. 내일 일찍 와서 계속 찾아보자.

3. 성찰

  • 내가 맡은 일에 대해 끊임없이 더 깊게 생각하는 습관을 들이자

📖 02.16 수요일

1. 공부 진행 상황

  • 기능 추가/수정
    • disconnect 1차 구현 (1:1용) → N:M 으로 수정 중
    • disconnect 동작 시 화상통화 송출도 연결 끊기 → removePeerFace 구현
    • ⭐️ N:M 화상통화 구현 시 화면시 2개씩 추가되는 현상 수정 완료
  • Frontend + Backend merge 완료
  • Algorithm N:M 그룹간 통화 예외처리 로직을 짜는 것이 알고리즘 이었다...후하

2. 기술적 고민

  • 소켓에 그룹네임을 추가하자 → 우선 데모까지는 정수 1 로 선언해두었다.
  • disconnect와, 다자간 영상통화/채팅를 각각 구현했는데 두 코드를 합치려하니 한 기능만 돌아가고 한 기능은 안된다. 계속 GetTracks가 안되고 있다는데, 원인을 몇 시간 째 못 찾고있다. → const 선언되어 있던 항목 삭제하니 수많은 풀이에도 안됐던 것이 돌아감
  • +) 스트림은 Promise에 의해 획득되기 때문에 getTracks()는 getUserMedia()보다 먼저 실행됩니다. 따라서 Promise 이후에 실행되도록 수정합니다
  • ⭐️ N:M 화상통화 구현 시 화면시 2개씩 추가되는 현상
    • sId 중복 제외하기
      1. isUserJoin = false 로 조건 추가. 어떤 Group에도 속하지 않을 때
// Overworld.js

// 남는 사람 기준
  socket.on("leave_succ", function(data){
    const user = charMap[data.removeSid];
    user.isUserJoin = false;
    removePeerFace(data.removeSid);
  })
// app.js

function removeUser(removeSid){
	...
	console.log("____________leave_group____________")
    socket.to(findGroupName).emit("leave_succ", {
      removeSid,
    }

 

                  2. user_call에서 GroupNumber를 조건문으로 다시 나눔 (조건 추가함)

                  3. 각 브라우저마다 user_call해서 joinGroup이 2번 되고 있었음 (GroupArr에 sId가 2번씩 추가 됨)

              • 서로 call을 하고 있어서 발생한 오류니, make→join이 아니라, make만 하기.
              • 그러면 user2는 만들어진 room에 들어가고, user1도 그 방으로 입장
              • 사진

        // app.js
        
        socket.on("user_call", async ({ caller, callee }) => {
            const user_caller = charMap[caller];
            const user_callee = charMap[callee];
        
            //callee의 방이 있으면 그냥 참가 함수(caller)
            // caller 1 & callee 1 => 문제
            // caller 0 & callee 1
            // caller 1 & callee 0 => 문제
            // caller 0 & callee 0
            let guest_gN = user_callee.groupNumber;
            let host_gN = user_caller.groupNumber;
        
            console.log(guest_gN, host_gN);
        
            if (guest_gN) {
              if (!host_gN) {
                await joinGroup(guest_gN, user_caller.socket, "ANON");
                console.log("1번", guest_gN, host_gN);
                user_caller.groupNumber = guest_gN;
              }
            } else if (!host_gN) {
              //guest x && host x
              user_caller.groupNumber = await makeGroup(user_caller.socket, "ANON");
              console.log("2번", guest_gN, host_gN);
            } else {
              // guest X && host O
              console.log("else일 때 hosst_gN: ", host_gN, "guest_gN: ", guest_gN);
            }
        });

+) [ ] 빈 배열 삭제하는 코드도 추가했다.

                  4. paintPeerFace의 streams.appendChild(div)에서 2개씩 들어가나?

                  5. Makegroup에서 groupName을 정수 1로 주면 안되나?

                  6. leave 전에 나간이의 sid나 groupnumber가 socket.rooms에 들어있다면 leave?

                  7. [] 빈 배열을 주변인이 leave한 걸로 취급해서 재구현해본다면?

                  8. 해결!
                      - let closer배열 = closer.filter() 지울거 거르고
                      - socket.emit(”leave_group”, plyer.id
                      - 핸들링법 변경!
                          - 나가는 사람과, 남는 사람을 기준으로 영상 추가-삭제 기준을 변경.
                          - 나가는 사람 - [Overworld.js] 원래 함수 자리에 while문을 추가해서, 내가 가지고 있는 다른 사람의 영상을 전부 삭제함.
                          - 남는 사람 - if문 밖에 남는사람 기준 “leave_succ”, removePeerFace
                   -
plyer.isUserJoin 이 false→true로 바뀌었다가 다시 false로 바꿔주지 않는 부분 해결 (350line)

        // Overworld.js
        
        async function handleAddStream (event, remoteSocketId, remoteNickname) {
            const peerStream = event.stream;
            console.log(peerStream);
            const user = charMap[remoteSocketId] // person.js에 있는 거랑 같이
            
            if (!user.isUserJoin) { // 유저가 어떤 그룹에도 속하지 않을 때 영상을 키겠다
              user.isUserJoin = true;
              try{
                await paintPeerFace(peerStream, remoteSocketId, remoteNickname);
              } catch (err) {
                console.error(err);
              }
            }
          }
        

3. 성찰

  • 해결방안을 떠올릴 때 항상 새로운 접근 방법을 떠올려 봐야 한다
  • 욕심이 크면 나를 잡아먹을 것이다. 성실하게, 최선의 노력을 다 하자.
  • 그래도 더 잘 하고 싶다. 체력관리 잘 하면서 더 시간 쪼개 공부하자.
  • 가장 일찍 출근했어도 팀원에게 피곤한 티 내지 말자.
  • 백엔드 관련 영상 틈틈히 보기
  • 나 자신에게 잘 했다고 토닥여줄 것!
  • 불안함은 내가 움직이지 않으면 절대 해소될 수 없다

📖 02.17 목요일

1. 공부 진행 상황

  • video 관련 함수에 try-catch / async-await 달기
    1. handleAddStream의 painPeerFace에 추가
    2. paintPeerFace함수 내부에도 추가
    3. → try-catch를 달면, 오류 때문에 서버가 터지는 일을 오류 메시지를 띄우는 것으로 대체함으로써 방지해준다.
  • 중간발표, 협력사 강연
  • Algorithm 완전탐색(하)

2. 기술적 고민


[백엔드 팀 공부 예정]

  • 금-저녁) 로그인/회원가입 (+미들웨어, postman)
  • 토-낮) API서버, AWS서버 배포 (HTTP~HTTPS)
  • Table join - 시퀄라이즈 사용시 join→include 문법 사용. 변경 필요
  • WebRTC-Mesh → SFU로 변경할 예정

[추가할 것]

  • 카메라 디바이스 선택
  • 말풍선, 유저 닉네임 노출

3. 성찰

  • 과정도 중요하지만, 결과가 더 중요하다.

중간발표

[발표에 대해서]

  • 발표 후 포스터 세션 이어지니까, 피피티에 팀 소개 페이지 + 얼굴 사진 첨부할 것!
  • 폰트 크기 너무 작게 하면 X, 글 그대로 줄줄 읽지 말 것.
  • 3.10 실제 발표때는 청중 반응이 없을거임. 팀원이 답변하지 마라.
    질문,의견을 구하려면 반드시 답변이 나오게 해야 함. 최소화하길
  • 시연할 때는, 철저히 연출해서 할 것. 라이브(임기응변X)로 하지 마라.
  • Get to the Point 제대로 잡기. 너무 구구절절 설명할 필요 없음. 핵심만 보여주기.
  • 장표(PPT)를 만들 때 최종본을 만들겠다는 마음으로 만들어라. 중간에 잘못되면 바로 바꿔라. 나중에 못 고친다.
  • ppt에 역할 분담 세세하게 적은 것.. 맡은 게 없어보이는 사람은 취업을 못한다.
  • 지훈조 - 분석을 잘 하라는게 아니라, 소프트웨어 엔지니어 개발을 해야 한다고.
  • 유저가 사용할 수 있는 프로그램(기능)을 만들어야 한다고.
  • 우리가 잘났다는 것을 표현하기 위해 한게 있으면 이런걸 했다고 표현을 해야 한다.
  • 우리는 개발을 잘 할 수 있어요, 많이 할 수 있어요 를 강조해야 한다.
  • 발표를 꼭 리더가 할 필요는 없다. 발표를 잘 해야 한다.
  • 발표는 모노톤(임팩트X)으로 하면 안된다. Up and Down이 있어야 한다!
  • 임기응변 함부로 하지 마라. 문제가 있으니 잠시만 기다려주세요. 라고 이야기해라.
  • 긴장해서 빨라지는 것. 의식적으로 느리게 발표하는 연습 해라. 모노톤으로 느리게X!!
  • 발표시 잔얘기(준비하지 않은 이야기) 하지 마라. 마이크가 비어도 괜찮다.
  • 바탕화면 심플하게 바꿔라. 흰 배경이나 검은색
  • 기술적 챌린지는 불렛 타입으로 짧게 딱 딱. (해결방안은 자세히)

[우리조]

  • 아트룸이 공용공간인데, 너무 프로토타입처럼 이야기함. 이런 체험관이 있다 라고 하기
  • 아트룸을 셋이 하는게 맞나요?
  • 데모 시나리오 더 재밌게 만들어라
  • 기초를 먼저 하고 다른 방들을 더 만들려는 방향 자체는 좋음
  • 방을 들어가는 곳에 문이나, 화살표 등으로 눈에 보이게 하기
  • 영상이 누구 캐릭터인지 모르겠음. 따로 있는 느낌. 채팅창도
  • 다 한글인데 영어가 나오는 것. 굳이 영어 쓸 필요X, 통일해라
  • 너무 게더타운과 똑같아서 api를 가져와서 쓴 것 같은 느낌이 남. → 게더타운을 모티브로 해서, 직접 빌드해봤다 라는 멘트 필요!!
  • 3D룸도 이런 노력 했다는 언급 더 필요! 우리가 했다는 것을 강조
  • 로비와 각 테마 방과의 거리감. 평범-화려
  • 기술적 챌린지 → 더 구체적으로!!!! 이렇게 해결했다 Problem-Solution. 해결이 더 중요
  • 작가룸 방은 구현 안 하는게 나을 듯. 거기에 시간이 불필요하게 쏟아진게 보임
  • 너무 모노톤 발표다.




댓글