N:M 코드 테스트
→ test따로 하려다가, 시간 관계 상 바로 프론트 코드에 넣어 바로바로 수정하며 테스트 진행함.
overworld.js - N:M connection 코드 합치기 (union-find or stack)
→ 알고리즘X, 스택 사용.
Algorithm
group = [
{ caller : "-----socket ID-----",
callee : "-----socket ID-----"
},
{
caller : "-----socket ID-----",
callee : "-----socket ID-----"
},
...
]
//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);
}
}
}
// 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
XAlgorithm
N:M 그룹간 통화 예외처리 로직을 짜는 것이 알고리즘 이었다...후하소켓에 그룹네임을 추가하자 → 우선 데모까지는 정수 1 로 선언해두었다.
disconnect와, 다자간 영상통화/채팅를 각각 구현했는데 두 코드를 합치려하니 한 기능만 돌아가고 한 기능은 안된다. 계속 GetTracks가 안되고 있다는데, 원인을 몇 시간 째 못 찾고있다. → const 선언되어 있던 항목 삭제하니 수많은 풀이에도 안됐던 것이 돌아감
+) 스트림은 Promise에 의해 획득되기 때문에 getTracks()는 getUserMedia()보다 먼저 실행됩니다. 따라서 Promise 이후에 실행되도록 수정합니다
⭐️ N:M 화상통화 구현 시 화면시 2개씩 추가되는 현상
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,
}
user_call에서 GroupNumber를 조건문으로 다시 나눔 (조건 추가함)
각 브라우저마다 user_call해서 joinGroup이 2번 되고 있었음 (GroupArr에 sId가 2번씩 추가 됨)
// 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);
}
});
+) [ ] 빈 배열 삭제하는 코드도 추가했다.
paintPeerFace의 streams.appendChild(div)에서 2개씩 들어가나?
Makegroup에서 groupName을 정수 1로 주면 안되나?
leave 전에 나간이의 sid나 groupnumber가 socket.rooms에 들어있다면 leave?
[] 빈 배열을 주변인이 leave한 걸로 취급해서 재구현해본다면?
해결!
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);
}
}
}
handleAddStream의 painPeerFace에 추가
paintPeerFace함수 내부에도 추가
→ try-catch를 달면, 오류 때문에 서버가 터지는 일을 오류 메시지를 띄우는 것으로 대체함으로써 방지해준다.
Algorithm
완전탐색(하)[백엔드 팀 공부 예정]
[추가할 것]
과정도 중요하지만, 결과가 더 중요하다.
와우 메모 양이 장난이 아니네!