ํ๋ก ํธ์๋์์ WebRTC ํ๋ฉด ๊ณต์ ๋ฅผ ๊ตฌํํ๋ ์ข ํฉ ๊ฐ์ด๋. ๋ฐ์คํฌํฑ ์บก์ฒ, ์คํธ๋ฆฌ๋ฐ ๊ธฐ์ , ๋ณด์ ๊ณ ๋ ค์ฌํญ ๋ฐ ๊ธ๋ก๋ฒ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ํ ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ๋ค๋ฃน๋๋ค.
ํ๋ก ํธ์๋ WebRTC ํ๋ฉด ๊ณต์ : ๊ธ๋ก๋ฒ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ํ ๋ฐ์คํฌํฑ ์บก์ฒ ๋ฐ ์คํธ๋ฆฌ๋ฐ
์น ์ค์๊ฐ ํต์ (Web Real-Time Communication, WebRTC)์ ์น์์์ ์ค์๊ฐ ํต์ ์ ํ๋ช ์ ์ผ์ผ์ผ ๋ธ๋ผ์ฐ์ ๋ด์์ ์ง์ P2P(peer-to-peer) ์ค๋์ค, ๋น๋์ค, ๋ฐ์ดํฐ ์ ์ก์ ๊ฐ๋ฅํ๊ฒ ํ์ต๋๋ค. WebRTC๊ฐ ์ง์ํ๋ ๊ฐ์ฅ ๊ฐ๋ ฅํ ๊ธฐ๋ฅ ์ค ํ๋๋ ํ๋ฉด ๊ณต์ ๋ก, ์ฌ์ฉ์๊ฐ ์์ ์ ๋ฐ์คํฌํฑ์ด๋ ํน์ ์ ํ๋ฆฌ์ผ์ด์ ์ฐฝ์ ๋ค๋ฅธ ์ฌ๋๋ค๊ณผ ์ค์๊ฐ์ผ๋ก ๊ณต์ ํ ์ ์๊ฒ ํด์ค๋๋ค. ์ด ๊ธฐ๋ฅ์ ์จ๋ผ์ธ ํ์, ์๊ฒฉ ํ์ , ๊ธฐ์ ์ง์ ๋ฐ ๊ต์ก ํ๋ซํผ์์ ๋งค์ฐ ์ค์ํ๋ฉฐ, ์ง๋ฆฌ์ ๊ฒฝ๊ณ๋ฅผ ๋์ด ์ํํ ์ปค๋ฎค๋์ผ์ด์ ์ ์ด์งํฉ๋๋ค. ์ด ์ข ํฉ ๊ฐ์ด๋์์๋ ํ๋ก ํธ์๋์์ WebRTC ํ๋ฉด ๊ณต์ ๋ฅผ ๊ตฌํํ๋ ๋ณต์กํ ๊ณผ์ , ํนํ ๋ฐ์คํฌํฑ ์บก์ฒ ๋ฐ ์คํธ๋ฆฌ๋ฐ ๊ธฐ์ , ๋ณด์ ๊ณ ๋ ค์ฌํญ, ๊ทธ๋ฆฌ๊ณ ๊ฒฌ๊ณ ํ๊ณ ์ ์ธ๊ณ์ ์ผ๋ก ์ ๊ทผ ๊ฐ๋ฅํ ์ ํ๋ฆฌ์ผ์ด์ ๊ฐ๋ฐ์ ์ํ ๋ชจ๋ฒ ์ฌ๋ก์ ๋ํด ์์ธํ ์์๋ด ๋๋ค.
WebRTC ํ๋ฉด ๊ณต์ ์ดํดํ๊ธฐ
WebRTC ํ๋ฉด ๊ณต์ ๋ getUserMedia API๋ฅผ ์ฌ์ฉํ์ฌ ์ฌ์ฉ์์ ํ๋ฉด์ด๋ ํน์ ์ฐฝ์ ์ ๊ทผํฉ๋๋ค. ๊ทธ๋ฌ๋ฉด ๋ธ๋ผ์ฐ์ ๋ ์ ํ๋ ์์ค์์ ๋น๋์ค ์คํธ๋ฆผ์ ์บก์ฒํ์ฌ WebRTC ์ธ์
์ ๋ค๋ฅธ ์ฐธ๊ฐ์์๊ฒ ์ ์กํฉ๋๋ค. ์ด ๊ณผ์ ์ ๋ค์๊ณผ ๊ฐ์ ๋ช ๊ฐ์ง ์ฃผ์ ๋จ๊ณ๋ก ์ด๋ฃจ์ด์ง๋๋ค:
- ์ฌ์ฉ์ ์ ํ: ์ฌ์ฉ์๊ฐ ํ๋ฉด ๊ณต์ ํ๋ก์ธ์ค๋ฅผ ์์ํ๊ณ ๊ณต์ ํ ํ๋ฉด์ด๋ ์ฐฝ์ ์ ํํฉ๋๋ค.
- ์คํธ๋ฆผ ํ๋:
getUserMediaAPI๋ฅผ ์ฌ์ฉํ์ฌ ์ ํ๋ ์์ค๋ฅผ ๋ํ๋ด๋ ๋น๋์ค ์คํธ๋ฆผ์ ํ๋ํฉ๋๋ค. - ํผ์ด ์ฐ๊ฒฐ: ๋น๋์ค ์คํธ๋ฆผ์ด WebRTC ํผ์ด ์ฐ๊ฒฐ์ ์ถ๊ฐ๋ฉ๋๋ค.
- ์๊ทธ๋๋ง: ์๊ทธ๋๋ง ์๋ฒ๊ฐ ํผ์ด ๊ฐ์ SDP(Session Description Protocol) offer ๋ฐ answer ๊ตํ์ ์ค๊ฐํ์ฌ ์ฐ๊ฒฐ์ ์ค์ ํฉ๋๋ค.
- ์คํธ๋ฆฌ๋ฐ: ๋น๋์ค ์คํธ๋ฆผ์ด ํ ํผ์ด์์ ๋ค๋ฅธ ํผ์ด๋ก ์ค์๊ฐ์ผ๋ก ์ ์ก๋ฉ๋๋ค.
getDisplayMedia๋ฅผ ์ด์ฉํ ๋ฐ์คํฌํฑ ์บก์ฒ ๊ตฌํ
ํ๋ฉด ๊ณต์ ๋ฅผ ์ํด ํน๋ณํ ์ค๊ณ๋ getUserMedia์ ํ์ฅ์ธ getDisplayMedia API๋ ๋ฐ์คํฌํฑ ์บก์ฒ ๊ณผ์ ์ ๋จ์ํํฉ๋๋ค. ์ด API๋ ์ฌ์ฉ์์ ํ๋ฉด์ด๋ ํน์ ์ ํ๋ฆฌ์ผ์ด์
์ฐฝ์ ๋ํ ์ ๊ทผ์ ์์ฒญํ๋ ๋ ๊ฐ์ํ๋๊ณ ์์ ํ ๋ฐฉ๋ฒ์ ์ ๊ณตํฉ๋๋ค. ์ด๋ ์ค๋๋๊ณ ๋ ์์ ํ ๋ฐฉ๋ฒ๋ค์ ๋์ฒดํ๋ฉฐ, ์ฌ์ฉ์์๊ฒ ํฅ์๋ ๊ฐ์ธ ์ ๋ณด ๋ณดํธ ๋ฐ ์ ์ด ๊ธฐ๋ฅ์ ์ ๊ณตํฉ๋๋ค.
getDisplayMedia ๊ธฐ๋ณธ ์ฌ์ฉ๋ฒ
๋ค์ ์ฝ๋ ์ค๋ํซ์ getDisplayMedia์ ๊ธฐ๋ณธ ์ฌ์ฉ๋ฒ์ ๋ณด์ฌ์ค๋๋ค:
async function startScreenShare() {
try {
const stream = await navigator.mediaDevices.getDisplayMedia({
video: true,
audio: true //์ ํ์ฌํญ: ํ๋ฉด์ ์ค๋์ค๋ ์บก์ฒํ๊ณ ์ถ์ ๊ฒฝ์ฐ
});
// ์คํธ๋ฆผ ์ฒ๋ฆฌ (์: video ์์์ ํ์)
const videoElement = document.getElementById('screenShareVideo');
videoElement.srcObject = stream;
//์คํธ๋ฆผ ์ข
๋ฃ ์ฒ๋ฆฌ
stream.getVideoTracks()[0].addEventListener('ended', () => {
stopScreenShare(); //๊ณต์ ์ค์ง๋ฅผ ์ํ ์ฌ์ฉ์ ์ ์ ํจ์
});
} catch (err) {
console.error('Error accessing screen:', err);
// ์ค๋ฅ ์ฒ๋ฆฌ (์: ์ฌ์ฉ์๊ฐ ๊ถํ์ ๊ฑฐ๋ถํ ๊ฒฝ์ฐ)
}
}
function stopScreenShare() {
if (videoElement.srcObject) {
const stream = videoElement.srcObject;
const tracks = stream.getTracks();
tracks.forEach(track => track.stop());
videoElement.srcObject = null;
}
}
์ด ์ฝ๋ ์ค๋ํซ์ ๋จผ์ ๋น๋๊ธฐ ํจ์ startScreenShare๋ฅผ ์ ์ํฉ๋๋ค. ์ด ํจ์ ๋ด์์, ํ๋ฉด์ผ๋ก๋ถํฐ ๋น๋์ค์ ์ ํ์ ์ผ๋ก ์ค๋์ค๋ฅผ ์์ฒญํ๋ ์ต์
๊ณผ ํจ๊ป navigator.mediaDevices.getDisplayMedia๋ฅผ ํธ์ถํฉ๋๋ค. ๋ฐํ๋ ์คํธ๋ฆผ์ ์บก์ฒ๋ ํ๋ฉด์ ํ์ํ๊ธฐ ์ํด video ์์์ ํ ๋น๋ฉ๋๋ค. ์ด ์ฝ๋๋ ๋ํ ์ค๋ฅ ์ฒ๋ฆฌ ๋ฐ ์คํธ๋ฆผ์ด ๋๋ ๋ ํ๋ฉด ๊ณต์ ๋ฅผ ์ค์งํ๋ ๋ฉ์ปค๋์ฆ์ ํฌํจํฉ๋๋ค. stopScreenShare ํจ์๋ ์คํธ๋ฆผ์ ๋ชจ๋ ํธ๋์ ์ ์ ํ๊ฒ ์ค์งํ์ฌ ๋ฆฌ์์ค๋ฅผ ํด์ ํ๋๋ก ๊ตฌํ๋์์ต๋๋ค.
getDisplayMedia ๊ตฌ์ฑ ์ต์
getDisplayMedia API๋ ์ ํ์ ์ธ MediaStreamConstraints ๊ฐ์ฒด๋ฅผ ๋ฐ์ ๋น๋์ค ์คํธ๋ฆผ์ ๋ํ ๋ค์ํ ์ต์
์ ์ง์ ํ ์ ์์ต๋๋ค. ์ด๋ฌํ ์ต์
์๋ ๋ค์์ด ํฌํจ๋ ์ ์์ต๋๋ค:
video: ๋น๋์ค ์คํธ๋ฆผ์ ์์ฒญํ ์ง ์ฌ๋ถ๋ฅผ ๋ํ๋ด๋ ๋ถ๋ฆฌ์ธ ๊ฐ(ํ์). ์ถ๊ฐ ์ ์ฝ ์กฐ๊ฑด์ ์ง์ ํ๋ ๊ฐ์ฒด์ผ ์๋ ์์ต๋๋ค.audio: ์ค๋์ค ์คํธ๋ฆผ์ ์์ฒญํ ์ง ์ฌ๋ถ๋ฅผ ๋ํ๋ด๋ ๋ถ๋ฆฌ์ธ ๊ฐ(์ ํ์ฌํญ). ์์คํ ์ค๋์ค๋ ๋ง์ดํฌ ์ค๋์ค๋ฅผ ์บก์ฒํ๋ ๋ฐ ์ฌ์ฉํ ์ ์์ต๋๋ค.preferCurrentTab: (๋ถ๋ฆฌ์ธ) ํ์ฌ ํญ์ ์ฌ์ฉ์์๊ฒ ๋จผ์ ๊ณต์ ์ต์ ์ผ๋ก ์ ๊ณตํด์ผ ํ๋ค๋ ๋ธ๋ผ์ฐ์ ์ ๋ํ ํํธ์ ๋๋ค. (์คํ์ ๊ธฐ๋ฅ)surfaceSwitching: (๋ถ๋ฆฌ์ธ) ์บก์ฒ๊ฐ ์งํ๋๋ ๋์ ์ฌ์ฉ์๊ฐ ๊ณต์ ์ค์ธ ํ๋ฉด์ ์ ํํ ์ ์๋์ง ์ฌ๋ถ์ ๋ํ ๋ธ๋ผ์ฐ์ ํํธ์ ๋๋ค. (์คํ์ ๊ธฐ๋ฅ)systemAudio: (๋ฌธ์์ด) ์์คํ ์ค๋์ค๋ฅผ ๊ณต์ ํด์ผ ํ๋์ง ์ฌ๋ถ๋ฅผ ๋ํ๋ ๋๋ค. ํ์ฉ๋๋ ๊ฐ์ `"include"`, `"exclude"`, `"notAllowed"`์ ๋๋ค. (์คํ์ ์ด๋ฉฐ ๋ธ๋ผ์ฐ์ ์ ๋ฐ๋ผ ๋ค๋ฆ)
๋ ๋ง์ ์ต์ ์ ์ฌ์ฉํ ์์ :
async function startScreenShare() {
try {
const stream = await navigator.mediaDevices.getDisplayMedia({
video: {
cursor: "always", // ๋๋ "motion" ๋๋ "never"
displaySurface: "browser", // ๋๋ "window", "application", "monitor"
logicalSurface: true, //๋ฌผ๋ฆฌ์ ํ๋ฉด ๋์ ๋
ผ๋ฆฌ์ ํ๋ฉด์ ๊ณ ๋ คํฉ๋๋ค.
},
audio: true
});
// ์คํธ๋ฆผ ์ฒ๋ฆฌ (์: video ์์์ ํ์)
const videoElement = document.getElementById('screenShareVideo');
videoElement.srcObject = stream;
//์คํธ๋ฆผ ์ข
๋ฃ ์ฒ๋ฆฌ
stream.getVideoTracks()[0].addEventListener('ended', () => {
stopScreenShare(); //๊ณต์ ์ค์ง๋ฅผ ์ํ ์ฌ์ฉ์ ์ ์ ํจ์
});
} catch (err) {
console.error('Error accessing screen:', err);
// ์ค๋ฅ ์ฒ๋ฆฌ (์: ์ฌ์ฉ์๊ฐ ๊ถํ์ ๊ฑฐ๋ถํ ๊ฒฝ์ฐ)
}
}
์ฌ์ฉ์ ๊ถํ ์ฒ๋ฆฌ
getDisplayMedia๋ฅผ ํธ์ถํ๋ฉด ๋ธ๋ผ์ฐ์ ๋ ์ฌ์ฉ์์๊ฒ ํ๋ฉด์ด๋ ์ฐฝ์ ๊ณต์ ํ ๊ถํ์ ๋ถ์ฌํ๋๋ก ์์ฒญํฉ๋๋ค. ์ฌ์ฉ์์ ์๋ต์ ์ ์ ํ๊ฒ ์ฒ๋ฆฌํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค. ์ฌ์ฉ์๊ฐ ๊ถํ์ ๋ถ์ฌํ๋ฉด getDisplayMedia๊ฐ ๋ฐํํ๋ ํ๋ก๋ฏธ์ค๋ MediaStream ๊ฐ์ฒด๋ก ํด๊ฒฐ๋ฉ๋๋ค. ์ฌ์ฉ์๊ฐ ๊ถํ์ ๊ฑฐ๋ถํ๋ฉด ํ๋ก๋ฏธ์ค๋ DOMException์ผ๋ก ๊ฑฐ๋ถ๋ฉ๋๋ค. ์ฌ์ฉ์ ์นํ์ ์ธ ๊ฒฝํ์ ์ ๊ณตํ๊ธฐ ์ํด ๋ ์๋๋ฆฌ์ค๋ฅผ ๋ชจ๋ ์ฒ๋ฆฌํด์ผ ํฉ๋๋ค. ๊ถํ ๊ฑฐ๋ถ ์ ์ฌ์ฉ์์๊ฒ ์ ์ตํ ๋ฉ์์ง๋ฅผ ํ์ํ๊ณ ๋ธ๋ผ์ฐ์ ์ค์ ์์ ํ๋ฉด ๊ณต์ ๋ฅผ ํ์ฑํํ๋ ๋ฐฉ๋ฒ์ ์๋ดํ์ธ์.
getDisplayMedia ๋ชจ๋ฒ ์ฌ๋ก
- ํ์ํ ๊ถํ๋ง ์์ฒญ: ์ ํ๋ฆฌ์ผ์ด์ ์ ์ ๋์ ์ผ๋ก ํ์ํ ๊ถํ๋ง ์์ฒญํ์ธ์. ์๋ฅผ ๋ค์ด, ํน์ ์ ํ๋ฆฌ์ผ์ด์ ์ฐฝ๋ง ๊ณต์ ํด์ผ ํ๋ ๊ฒฝ์ฐ ์ ์ฒด ํ๋ฉด์ ๋ํ ์ ๊ทผ์ ์์ฒญํ์ง ๋ง์ธ์. ์ด๋ ์ฌ์ฉ์ ๊ฐ์ธ ์ ๋ณด ๋ณดํธ์ ์ ๋ขฐ๋ฅผ ํฅ์์ํต๋๋ค.
- ์ค๋ฅ๋ฅผ ์ ์์ ์ผ๋ก ์ฒ๋ฆฌ: ์ฌ์ฉ์๊ฐ ๊ถํ์ ๊ฑฐ๋ถํ๊ฑฐ๋ ํ๋ฉด ๊ณต์ ๋ฅผ ์ฌ์ฉํ ์ ์๋ ๊ฒฝ์ฐ๋ฅผ ์ ์์ ์ผ๋ก ์ฒ๋ฆฌํ๊ธฐ ์ํด ๊ฒฌ๊ณ ํ ์ค๋ฅ ์ฒ๋ฆฌ ๊ธฐ๋ฅ์ ๊ตฌํํ์ธ์.
- ๋ช ํํ ์ง์นจ ์ ๊ณต: ์ฌ์ฉ์๊ฐ ๋ฌธ์ ๋ฅผ ๊ฒช์ ๊ฒฝ์ฐ ๋ธ๋ผ์ฐ์ ์์ ํ๋ฉด ๊ณต์ ๋ฅผ ํ์ฑํํ๋ ๋ฐฉ๋ฒ์ ๋ํ ๋ช ํํ๊ณ ๊ฐ๊ฒฐํ ์ง์นจ์ ์ ๊ณตํ์ธ์.
- ์ฌ์ฉ์ ๊ฐ์ธ ์ ๋ณด ์กด์ค: ํญ์ ์ฌ์ฉ์์ ๊ฐ์ธ ์ ๋ณด๋ฅผ ์กด์คํ๊ณ ํ๋ฉด ๊ณต์ ๊ณผ์ ๊ณผ ์ง์ ๊ด๋ จ์ด ์๋ ๋ฏผ๊ฐํ ์ ๋ณด๋ฅผ ์บก์ฒํ๊ฑฐ๋ ์ ์กํ์ง ๋ง์ธ์.
์บก์ฒ๋ ํ๋ฉด ์คํธ๋ฆฌ๋ฐํ๊ธฐ
์บก์ฒ๋ ํ๋ฉด์ ๋ํ๋ด๋ MediaStream์ ์ป์ผ๋ฉด ์ด๋ฅผ WebRTC ์ธ์
์ ๋ค๋ฅธ ์ฐธ๊ฐ์์๊ฒ ์คํธ๋ฆฌ๋ฐํ ์ ์์ต๋๋ค. ์ด๋ ์คํธ๋ฆผ์ WebRTC ํผ์ด ์ฐ๊ฒฐ์ ์ถ๊ฐํ๊ณ ์๊ฒฉ ํผ์ด์๊ฒ ์ ์กํ๋ ๊ฒ์ ํฌํจํฉ๋๋ค. ๋ค์ ์ฝ๋ ์ค๋ํซ์ ๊ธฐ์กด ํผ์ด ์ฐ๊ฒฐ์ ํ๋ฉด ๊ณต์ ์คํธ๋ฆผ์ ์ถ๊ฐํ๋ ๋ฐฉ๋ฒ์ ๋ณด์ฌ์ค๋๋ค:
async function addScreenShareToPeerConnection(peerConnection) {
try {
const stream = await navigator.mediaDevices.getDisplayMedia({
video: true,
audio: true
});
stream.getTracks().forEach(track => {
peerConnection.addTrack(track, stream);
});
return stream;
} catch (err) {
console.error('Error adding screen share to peer connection:', err);
// ์ค๋ฅ ์ฒ๋ฆฌ
return null;
}
}
์ด ์์ ์์ addScreenShareToPeerConnection ํจ์๋ RTCPeerConnection ๊ฐ์ฒด๋ฅผ ์
๋ ฅ์ผ๋ก ๋ฐ์ต๋๋ค. ๊ทธ๋ฐ ๋ค์ getDisplayMedia๋ฅผ ํธ์ถํ์ฌ ํ๋ฉด ๊ณต์ ์คํธ๋ฆผ์ ์ป์ต๋๋ค. ์ด ์คํธ๋ฆผ์ ํธ๋๋ค์ addTrack ๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ฌ ํผ์ด ์ฐ๊ฒฐ์ ์ถ๊ฐ๋ฉ๋๋ค. ์ด๋ ๊ฒ ํ๋ฉด ํ๋ฉด ๊ณต์ ์คํธ๋ฆผ์ด ์๊ฒฉ ํผ์ด์๊ฒ ์ ์ก๋ฉ๋๋ค. ์ด ํจ์๋ ๋์ค์ ํ์ํ ๊ฒฝ์ฐ ์ค์งํ ์ ์๋๋ก ์คํธ๋ฆผ์ ๋ฐํํฉ๋๋ค.
์คํธ๋ฆฌ๋ฐ ์ฑ๋ฅ ์ต์ ํ
์ํํ๊ณ ๋ฐ์์ฑ์ด ์ข์ ํ๋ฉด ๊ณต์ ๊ฒฝํ์ ๋ณด์ฅํ๋ ค๋ฉด ์คํธ๋ฆฌ๋ฐ ์ฑ๋ฅ์ ์ต์ ํํ๋ ๊ฒ์ด ํ์์ ์ ๋๋ค. ๋ค์ ๊ธฐ์ ๋ค์ ๊ณ ๋ คํ์ธ์:
- ์ฝ๋ฑ ์ ํ: ํ๋ฉด ๊ณต์ ์คํธ๋ฆผ์ ์ ํฉํ ๋น๋์ค ์ฝ๋ฑ์ ์ ํํ์ธ์. VP8 ๋๋ H.264์ ๊ฐ์ ์ฝ๋ฑ์ WebRTC์ ์ผ๋ฐ์ ์ผ๋ก ์ฌ์ฉ๋์ง๋ง, ์ต์ ์ ์ ํ์ ํน์ ์ฌ์ฉ ์ฌ๋ก ๋ฐ ๋ธ๋ผ์ฐ์ ์ง์์ ๋ฐ๋ผ ๋ค๋ฆ ๋๋ค. ๋คํธ์ํฌ ์กฐ๊ฑด์ ๋ฐ๋ผ ๋น๋์ค ํ์ง์ ๋์ ์ผ๋ก ์กฐ์ ํ๋ SVC(Scalable Video Coding) ์ฝ๋ฑ ์ฌ์ฉ์ ๊ณ ๋ คํด ๋ณด์ธ์.
- ํด์๋ ๋ฐ ํ๋ ์ ์๋: ๋น๋์ค ํ์ง๊ณผ ๋์ญํญ ์๋น์ ๊ท ํ์ ๋ง์ถ๊ธฐ ์ํด ํ๋ฉด ๊ณต์ ์คํธ๋ฆผ์ ํด์๋์ ํ๋ ์ ์๋๋ฅผ ์กฐ์ ํ์ธ์. ํด์๋๋ ํ๋ ์ ์๋๋ฅผ ๋ฎ์ถ๋ฉด ์ ์ก๋๋ ๋ฐ์ดํฐ ์์ ํฌ๊ฒ ์ค์ผ ์ ์์ผ๋ฉฐ, ํนํ ์ ๋์ญํญ ํ๊ฒฝ์์ ์ ์ฉํฉ๋๋ค.
- ๋์ญํญ ์ถ์ : ์ฌ์ฉ ๊ฐ๋ฅํ ๋์ญํญ์ ๋ฐ๋ผ ๋น๋์ค ํ์ง์ ๋์ ์ผ๋ก ์กฐ์ ํ๊ธฐ ์ํด ๋์ญํญ ์ถ์ ๊ธฐ์ ์ ๊ตฌํํ์ธ์. WebRTC๋ ๋คํธ์ํฌ ์ํ๋ฅผ ๋ชจ๋ํฐ๋งํ๊ณ ๊ทธ์ ๋ฐ๋ผ ์คํธ๋ฆผ ๋งค๊ฐ๋ณ์๋ฅผ ์กฐ์ ํ๋ API๋ฅผ ์ ๊ณตํฉ๋๋ค.
- RTP ํค๋ ํ์ฅ: RTP(Real-time Transport Protocol) ํค๋ ํ์ฅ์ ์ฌ์ฉํ์ฌ ๊ณต๊ฐ ๋ฐ ์๊ฐ ๊ณ์ธต๊ณผ ๊ฐ์ ์คํธ๋ฆผ์ ๋ํ ์ถ๊ฐ ์ ๋ณด๋ฅผ ์ ๊ณตํ์ฌ ์ ์ํ ์คํธ๋ฆฌ๋ฐ์ ํ์ฉํ ์ ์์ต๋๋ค.
- ์คํธ๋ฆผ ์ฐ์ ์์ ์ง์ :
RTCRtpSender.setPriority()๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ฌ ํผ์ด ์ฐ๊ฒฐ์ ๋ค๋ฅธ ์คํธ๋ฆผ๋ณด๋ค ํ๋ฉด ๊ณต์ ์คํธ๋ฆผ์ ์ฐ์ ์์๋ฅผ ๋์ฌ ์ถฉ๋ถํ ๋์ญํญ์ ํ๋ณดํ๋๋ก ํ์ธ์.
๋ณด์ ๊ณ ๋ ค์ฌํญ
ํ๋ฉด ๊ณต์ ๋ ๋ฏผ๊ฐํ ๋ฐ์ดํฐ๋ฅผ ํฌํจํ๋ฏ๋ก ๋ณด์ ๊ณ ๋ ค์ฌํญ์ ์ ์คํ๊ฒ ๋ค๋ฃจ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค. ์ฌ์ฉ์์ ๊ฐ์ธ ์ ๋ณด๋ฅผ ๋ณดํธํ๊ณ ๋ฌด๋จ ์ ๊ทผ์ ๋ฐฉ์งํ๊ธฐ ์ํด ๋ค์ ๋ณด์ ์กฐ์น๋ฅผ ๊ตฌํํ์ธ์:
- HTTPS: ํด๋ผ์ด์ธํธ์ ์๋ฒ ๊ฐ์ ํต์ ์ ์ํธํํ๊ธฐ ์ํด ํญ์ HTTPS๋ฅผ ํตํด ์ ํ๋ฆฌ์ผ์ด์ ์ ์ ๊ณตํ์ธ์. ์ด๋ ๋์ฒญ์ ๋ฐฉ์งํ๊ณ ์ ์ก๋ ๋ฐ์ดํฐ์ ๋ฌด๊ฒฐ์ฑ์ ๋ณด์ฅํฉ๋๋ค.
- ์์ ํ ์๊ทธ๋๋ง: ํผ์ด ๊ฐ์ SDP offer ๋ฐ answer๋ฅผ ๊ตํํ๊ธฐ ์ํด ์์ ํ ์๊ทธ๋๋ง ๋ฉ์ปค๋์ฆ์ ์ฌ์ฉํ์ธ์. ์์ ํ์ง ์์ ์ฑ๋์ ํตํด ๋ฏผ๊ฐํ ์ ๋ณด๋ฅผ ํ๋ฌธ์ผ๋ก ์ ์กํ์ง ๋ง์ธ์. ์์ ํ ์๊ทธ๋๋ง์ ์ํด TLS ์ํธํ๊ฐ ์ ์ฉ๋ WebSocket ์ฌ์ฉ์ ๊ณ ๋ คํ์ธ์.
- ์ธ์ฆ ๋ฐ ์ธ๊ฐ: ์น์ธ๋ ์ฌ์ฉ์๋ง ํ๋ฉด ๊ณต์ ์ธ์ ์ ์ฐธ์ฌํ ์ ์๋๋ก ๊ฐ๋ ฅํ ์ธ์ฆ ๋ฐ ์ธ๊ฐ ๋ฉ์ปค๋์ฆ์ ๊ตฌํํ์ธ์. ํ๋ฉด ๊ณต์ ์คํธ๋ฆผ์ ๋ํ ์ ๊ทผ์ ํ์ฉํ๊ธฐ ์ ์ ์ฌ์ฉ์์ ์ ์์ ํ์ธํ์ธ์.
- ์ฝํ ์ธ ๋ณด์ ์ ์ฑ (CSP): CSP ํค๋๋ฅผ ์ฌ์ฉํ์ฌ ์ ํ๋ฆฌ์ผ์ด์ ์ด ๋ก๋ํ ์ ์๋ ์ฝํ ์ธ ์์ค๋ฅผ ์ ํํ์ธ์. ์ด๋ ๊ต์ฐจ ์ฌ์ดํธ ์คํฌ๋ฆฝํ (XSS) ๊ณต๊ฒฉ์ ๋ฐฉ์งํ๊ณ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ ์ฑ ์ฝ๋๊ฐ ์ฃผ์ ๋ ์ํ์ ์ค์ ๋๋ค.
- ๋ฐ์ดํฐ ์ํธํ: WebRTC๋ ๊ธฐ๋ณธ์ ์ผ๋ก SRTP(Secure Real-time Transport Protocol)๋ฅผ ์ฌ์ฉํ์ฌ ๋ฏธ๋์ด ์คํธ๋ฆผ์ ์ํธํํฉ๋๋ค. ํ๋ฉด ๊ณต์ ์คํธ๋ฆผ์ ๊ธฐ๋ฐ์ฑ์ ๋ณดํธํ๊ธฐ ์ํด SRTP๊ฐ ํ์ฑํ๋๊ณ ์ฌ๋ฐ๋ฅด๊ฒ ๊ตฌ์ฑ๋์๋์ง ํ์ธํ์ธ์.
- ์ ๊ธฐ์ ์ธ ์ ๋ฐ์ดํธ: ๋ณด์ ์ทจ์ฝ์ ์ ํจ์นํ๊ธฐ ์ํด WebRTC ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋ธ๋ผ์ฐ์ ๋ฅผ ์ต์ ์ํ๋ก ์ ์งํ์ธ์. ์ ๊ธฐ์ ์ผ๋ก ๋ณด์ ๊ถ๊ณ ๋ฅผ ๊ฒํ ํ๊ณ ์ต์ ์ ๋ฐ์ดํธ๋ฅผ ์ ์ํ๊ฒ ์ ์ฉํ์ธ์.
WebRTC ํ๋ฉด ๊ณต์ ์ ๊ธ๋ก๋ฒ ๊ณ ๋ ค์ฌํญ
์ ์ธ๊ณ ์ฌ์ฉ์๋ฅผ ๋์์ผ๋ก WebRTC ํ๋ฉด ๊ณต์ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ฐ๋ฐํ ๋๋ ๋ค์ ์์๋ฅผ ๊ณ ๋ คํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค:
- ๋คํธ์ํฌ ์กฐ๊ฑด: ๋คํธ์ํฌ ์กฐ๊ฑด์ ์ง์ญ๋ง๋ค ํฌ๊ฒ ๋ค๋ฆ ๋๋ค. ๋ค์ํ ๋์ญํญ๊ณผ ์ง์ฐ ์๊ฐ์ ์ฒ๋ฆฌํ๋๋ก ์ ํ๋ฆฌ์ผ์ด์ ์ ์ต์ ํํ์ธ์. ๋คํธ์ํฌ ์กฐ๊ฑด์ ๋ฐ๋ผ ๋น๋์ค ํ์ง์ ์กฐ์ ํ๋ ์ ์ํ ์คํธ๋ฆฌ๋ฐ ๊ธฐ์ ์ ๊ตฌํํ์ธ์. NAT ์ํ(traversal)๋ฅผ ์ฒ๋ฆฌํ๊ณ ๋ค๋ฅธ ์ง์ญ์์์ ์ฐ๊ฒฐ์ฑ์ ๋ณด์ฅํ๊ธฐ ์ํด ๊ธ๋ก๋ฒ TURN ์๋ฒ ๋คํธ์ํฌ๋ฅผ ์ฌ์ฉํ์ธ์.
- ๋ธ๋ผ์ฐ์ ํธํ์ฑ: WebRTC ์ง์์ ๋ธ๋ผ์ฐ์ ์ ๋ฒ์ ์ ๋ฐ๋ผ ๋ค๋ฆ ๋๋ค. ํธํ์ฑ๊ณผ ์ผ๊ด๋ ์ฌ์ฉ์ ๊ฒฝํ์ ๋ณด์ฅํ๊ธฐ ์ํด ๋ค์ํ ๋ธ๋ผ์ฐ์ ์์ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ฒ ์ ํ ํ ์คํธํ์ธ์. ๋ธ๋ผ์ฐ์ ๋ณ ์ฐจ์ด์ ์ ์ถ์ํํ๊ณ ๊ฐ๋ฐ ๊ณผ์ ์ ๋จ์ํํ๊ธฐ ์ํด WebRTC ์ด๋ํฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ์ธ์.
- ์ ๊ทผ์ฑ: ์ฅ์ ๊ฐ ์๋ ์ฌ์ฉ์๋ ํ๋ฉด ๊ณต์ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ ๊ทผํ ์ ์๋๋ก ๋ง๋์ธ์. ํค๋ณด๋ ๋ด๋น๊ฒ์ด์ ๋ฐ ์คํฌ๋ฆฐ ๋ฆฌ๋ ์ง์๊ณผ ๊ฐ์ ๋์ฒด ์ ๋ ฅ ๋ฐฉ๋ฒ์ ์ ๊ณตํ์ธ์. ๋ชจ๋ ์ฌ์ฉ์๊ฐ ์ฌ์ฉ์ ์ธํฐํ์ด์ค๋ฅผ ๋ช ํํ๊ณ ์ฝ๊ฒ ์ฌ์ฉํ ์ ์๋๋ก ๋ณด์ฅํ์ธ์.
- ํ์งํ: ๋ค์ํ ์ธ์ด์ ์ง์ญ์ ์ง์ํ๋๋ก ์ ํ๋ฆฌ์ผ์ด์ ์ ํ์งํํ์ธ์. ์ฌ์ฉ์ ์ธํฐํ์ด์ค๋ฅผ ๋ฒ์ญํ๊ณ ๋ฌธํ์ ์ผ๋ก ๊ด๋ จ๋ ์ฝํ ์ธ ๋ฅผ ์ ๊ณตํ์ธ์. ํ์งํ ๊ณผ์ ์ ๊ฐ์ํํ๊ธฐ ์ํด ๋ฒ์ญ ๊ด๋ฆฌ ์์คํ ์ฌ์ฉ์ ๊ณ ๋ คํ์ธ์.
- ์๊ฐ๋: ํ๋ฉด ๊ณต์ ์ธ์ ์ ์์ฝํ๊ณ ์กฐ์ ํ ๋ ์๊ฐ๋ ์ฐจ์ด๋ฅผ ๊ณ ๋ คํ์ธ์. ์ฌ์ฉ์๊ฐ ํ์ง ์๊ฐ๋๋ก ์ธ์ ์ ์์ฝํ๊ณ ์๊ฐ์ ์ฌ์ฉ์ ์นํ์ ์ธ ํ์์ผ๋ก ํ์ํ ์ ์๋ ๊ธฐ๋ฅ์ ์ ๊ณตํ์ธ์.
- ๋ฐ์ดํฐ ๊ฐ์ธ ์ ๋ณด ๋ณดํธ ๊ท์ : ์ฌ๋ฌ ๊ตญ๊ฐ ๋ฐ ์ง์ญ์ ๋ฐ์ดํฐ ๊ฐ์ธ ์ ๋ณด ๋ณดํธ ๊ท์ ์ ์ค์ํ์ธ์. ๊ฐ์ธ ๋ฐ์ดํฐ๋ฅผ ์์งํ๊ฑฐ๋ ์ฒ๋ฆฌํ๊ธฐ ์ ์ ์ฌ์ฉ์๋ก๋ถํฐ ๋์๋ฅผ ์ป์ผ์ธ์. ์ฌ์ฉ์ ๊ฐ์ธ ์ ๋ณด๋ฅผ ๋ณดํธํ๊ธฐ ์ํด ์ ์ ํ ๋ฐ์ดํฐ ๋ณด์ ์กฐ์น๋ฅผ ๊ตฌํํ์ธ์. ์๋ฅผ ๋ค์ด, ์ ๋ฝ์ GDPR(์ผ๋ฐ ๋ฐ์ดํฐ ๋ณดํธ ๊ท์ )์ ๋ฐ์ดํฐ ๊ฐ์ธ ์ ๋ณด ๋ณดํธ์ ๋ํ ์๊ฒฉํ ์๊ตฌ ์ฌํญ์ ๊ฐ์ง๊ณ ์์ต๋๋ค.
๊ณ ๊ธ ๊ธฐ์ ๋ฐ ๊ณ ๋ ค์ฌํญ
๊ฐ์ ๋ฐฐ๊ฒฝ ๋ฐ ๋น๋์ค ํจ๊ณผ
๊ฐ์ ๋ฐฐ๊ฒฝ ๋ฐ ๋น๋์ค ํจ๊ณผ๋ฅผ ํตํฉํ์ฌ ํ๋ฉด ๊ณต์ ๊ฒฝํ์ ํฅ์์ํค์ธ์. ์ด๋ฌํ ๊ธฐ๋ฅ์ ํ๋ฉด ๊ณต์ ์คํธ๋ฆผ์ ์๊ฐ์ ๋งค๋ ฅ์ ๊ฐ์ ํ๊ณ ์ฌ์ฉ์์๊ฒ ์์ ์ ์ธ๋ชจ์ ๋ํ ๋ ๋ง์ ์ ์ด๊ถ์ ์ ๊ณตํ ์ ์์ต๋๋ค. TensorFlow.js ๋ฐ Mediapipe์ ๊ฐ์ ์๋ฐ์คํฌ๋ฆฝํธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ์ฌ ํ๋ก ํธ์๋์์ ์ด๋ฌํ ๊ธฐ๋ฅ์ ํจ์จ์ ์ผ๋ก ๊ตฌํํ์ธ์.
์ค๋์ค ์ฒ๋ฆฌ๋ฅผ ํฌํจํ ํ๋ฉด ๊ณต์
ํ๋ฉด ๊ณต์ ์คํธ๋ฆผ์ ์ค๋์ค ํ์ง์ ๊ฐ์ ํ๊ธฐ ์ํด ์ค๋์ค ์ฒ๋ฆฌ ๊ธฐ์ ์ ํตํฉํ์ธ์. ์ค๋์ค ์ฒ๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ์ฌ ์์์ ์ค์ด๊ณ , ์์ฝ๋ฅผ ์ต์ ํ๊ณ , ์ค๋์ค ๋ ๋ฒจ์ ์ ๊ทํํ์ธ์. ์ด๋ ์ค๋์ค์ ์ ๋ช ๋๋ฅผ ํฌ๊ฒ ํฅ์์ํค๊ณ ์ ๋ฐ์ ์ธ ์ปค๋ฎค๋์ผ์ด์ ๊ฒฝํ์ ๊ฐ์ ํ ์ ์์ต๋๋ค.
์ฌ์ฉ์ ์ ์ ๊ฐ๋ฅํ ํ๋ฉด ๊ณต์ UI
์ฌ์ฉ์์๊ฒ ํ๋ฉด ๊ณต์ ๊ฒฝํ์ ๋ํ ๋ ๋ง์ ์ ์ด๊ถ์ ์ ๊ณตํ๊ธฐ ์ํด ์ฌ์ฉ์ ์ ์ ๊ฐ๋ฅํ ํ๋ฉด ๊ณต์ UI๋ฅผ ๋ง๋์ธ์. ์ฌ์ฉ์๊ฐ ํ๋ฉด์ ํน์ ์์ญ์ ์ ํํ์ฌ ๊ณต์ ํ๊ณ , ํ๋ฉด์ ์ฃผ์์ ๋ฌ๊ณ , ๋น๋์ค ํ์ง์ ์ ์ดํ ์ ์๋๋ก ํ์ฉํ์ธ์. ์ด๋ ์ฌ์ฉ์ ์ฐธ์ฌ๋ฅผ ๋์ด๊ณ ๋ ๋ง์ถคํ๋ ํ๋ฉด ๊ณต์ ๊ฒฝํ์ ์ ๊ณตํ ์ ์์ต๋๋ค.
ํ์ ํ๋ซํผ๊ณผ์ ํตํฉ
WebRTC ํ๋ฉด ๊ณต์ ๋ฅผ Slack, Microsoft Teams, Google Meet๊ณผ ๊ฐ์ ์ธ๊ธฐ ์๋ ํ์ ํ๋ซํผ๊ณผ ํตํฉํ์ธ์. ์ด๋ ์ฌ์ฉ์์๊ฒ ์ํํ๊ณ ํตํฉ๋ ์ปค๋ฎค๋์ผ์ด์ ๊ฒฝํ์ ์ ๊ณตํ ์ ์์ต๋๋ค. ํ๋ซํผ์ API๋ฅผ ์ฌ์ฉํ์ฌ ํ์ ํ๋ซํผ ๋ด์์ ์ง์ ํ๋ฉด ๊ณต์ ๋ฅผ ํ์ฑํํ์ธ์.
์์ : ๊ฐ๋จํ ๊ธ๋ก๋ฒ ํ๋ฉด ๊ณต์ ์ ํ๋ฆฌ์ผ์ด์
๊ฐ๋จํ ๊ธ๋ก๋ฒ ํ๋ฉด ๊ณต์ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์กฐ๋ฅผ ๊ฐ๋ตํ๊ฒ ์ค๋ช ํ๊ฒ ์ต๋๋ค. ์ด๋ ๊ฐ๋ต์ ์ธ ์์์ด๋ฉฐ ๋ ์์ธํ ๊ตฌํ์ด ํ์ํฉ๋๋ค.
- ์๊ทธ๋๋ง ์๋ฒ: ์ค์๊ฐ ํต์ ์ ์ํด Socket.IO๋ฅผ ์ฌ์ฉํ๋ Node.js ์๋ฒ. ์ด ์๋ฒ๋ ํผ์ด ๊ฐ์ SDP offer ๋ฐ answer ๊ตํ์ ์ค๊ฐํฉ๋๋ค.
- ํ๋ก ํธ์๋ (HTML, CSS, JavaScript): HTML, CSS, JavaScript๋ก ๊ตฌ์ถ๋ ์ฌ์ฉ์ ์ธํฐํ์ด์ค. ์ด ์ธํฐํ์ด์ค๋ ์ฌ์ฉ์ ์ํธ ์์ฉ, ํ๋ฉด ์บก์ฒ ๋ฐ WebRTC ํผ์ด ์ฐ๊ฒฐ ๊ด๋ฆฌ๋ฅผ ์ฒ๋ฆฌํฉ๋๋ค.
- TURN ์๋ฒ: NAT ์ํ๋ฅผ ์ฒ๋ฆฌํ๊ณ ๋ค๋ฅธ ์ง์ญ์์์ ์ฐ๊ฒฐ์ฑ์ ๋ณด์ฅํ๊ธฐ ์ํ ๊ธ๋ก๋ฒ TURN ์๋ฒ ๋คํธ์ํฌ. Xirsys ๋๋ Twilio์ ๊ฐ์ ์๋น์ค๊ฐ ์ด ์ธํ๋ผ๋ฅผ ์ ๊ณตํ ์ ์์ต๋๋ค.
ํ๋ก ํธ์๋ ์๋ฐ์คํฌ๋ฆฝํธ ์ฝ๋ (์์):
// ๋จ์ํ๋ ์์ - ํ๋ก๋์
์ฉ์ด ์๋
const socket = io('https://your-signaling-server.com');
const peerConnection = new RTCPeerConnection();
async function startScreenShare() {
//...์ด์ ๊ณผ ๋์ผํ getDisplayMedia ์ฝ๋...
stream.getTracks().forEach(track => peerConnection.addTrack(track, stream));
//... ICE ํ๋ณด ์ฒ๋ฆฌ, ์๊ทธ๋๋ง ์๋ฒ๋ฅผ ํตํ offer/answer ๊ตํ...
}
//ICE ํ๋ณด ์ฒ๋ฆฌ ์์ (๋จ์ํ๋จ)
peerConnection.onicecandidate = event => {
if (event.candidate) {
socket.emit('iceCandidate', event.candidate);
}
};
์ด ์์ ์ฝ๋๋ ๊ธฐ๋ณธ์ ์ธ ๊ตฌ์กฐ๋ฅผ ๋ณด์ฌ์ค๋๋ค. ์์ ํ ์ ํ๋ฆฌ์ผ์ด์ ์๋ ๊ฒฌ๊ณ ํ ์ค๋ฅ ์ฒ๋ฆฌ, UI ์์ ๋ฐ ๋ ์์ธํ ์๊ทธ๋๋ง ๋ก์ง์ด ํ์ํฉ๋๋ค.
๊ฒฐ๋ก
WebRTC ํ๋ฉด ๊ณต์ ๋ ์น์์ ์ค์๊ฐ ํ์ ๊ณผ ์ปค๋ฎค๋์ผ์ด์ ์ ๊ฐ๋ฅํ๊ฒ ํ๋ ๊ฐ๋ ฅํ ๊ธฐ์ ์ ๋๋ค. ๋ฐ์คํฌํฑ ์บก์ฒ, ์คํธ๋ฆฌ๋ฐ ๊ธฐ์ , ๋ณด์ ๊ณ ๋ ค์ฌํญ ๋ฐ ๊ธ๋ก๋ฒ ๊ณ ๋ ค์ฌํญ์ ๊ธฐ๋ณธ์ ์ดํดํจ์ผ๋ก์จ, ์ฌ์ฉ์๊ฐ ์ง๋ฆฌ์ ๊ฒฝ๊ณ๋ฅผ ๋์ด ํจ๊ณผ์ ์ผ๋ก ์ฐ๊ฒฐํ๊ณ ํ์ ํ ์ ์๋๋ก ํ๋ ๊ฒฌ๊ณ ํ๊ณ ์ ์ธ๊ณ์ ์ผ๋ก ์ ๊ทผ ๊ฐ๋ฅํ ํ๋ฉด ๊ณต์ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ถํ ์ ์์ต๋๋ค. ์ฐ๊ฒฐ๋ ์ธ์์ ์ํ ํ์ ์ ์ธ ์๋ฃจ์ ์ ๋ง๋ค๊ธฐ ์ํด WebRTC์ ์ ์ฐ์ฑ๊ณผ ๊ฐ๋ ฅํจ์ ํ์ฉํ์ธ์. WebRTC ๊ธฐ์ ์ด ๊ณ์ ๋ฐ์ ํจ์ ๋ฐ๋ผ, ์ต์ฒจ๋จ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ฐ๋ฐํ๊ธฐ ์ํด์๋ ์ต์ ๊ธฐ๋ฅ๊ณผ ๋ชจ๋ฒ ์ฌ๋ก์ ๋ํ ์ต์ ์ ๋ณด๋ฅผ ์ ์งํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค. SVC์ ๊ฐ์ ๊ณ ๊ธ ๊ธฐ์ ์ ํ์ํ๊ณ , ๋ธ๋ผ์ฐ์ ๋ณ ์ต์ ํ๋ฅผ ์ฐ๊ตฌํ๋ฉฐ, ์ ์ธ๊ณ ์ฌ์ฉ์์๊ฒ ์ํํ๊ณ ์์ ํ ํ๋ฉด ๊ณต์ ๊ฒฝํ์ ์ ๊ณตํ๊ธฐ ์ํด ์ ํ๋ฆฌ์ผ์ด์ ์ ์ง์์ ์ผ๋ก ํ ์คํธํ์ธ์.