5.Code Chat - asdfgl98/Project-CodeBuddy GitHub Wiki
- CodeMirror ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํด ์นํ์ด์ง์์ Code Editor๋ฅผ ๊ตฌํํ์์ต๋๋ค.
- ์ ๋ Back-end ํํธ๋ฅผ ๋ด๋นํ์์ง๋ง ํ๋ก์ ํธ๊ฐ ์์๋๊ธฐ ์ codemirror ์ฌ์ฉ๋ฒ์ ๊ณต๋ถํ์ฌ
์ฌ์ ์ ๊ตฌํ์ ํด ๋์๊ธฐ ๋๋ฌธ์ ํ๋ก์ ํธ๊ฐ ์์๋์์ ๋ Front๋ฅผ ๋ด๋นํ๋ ํ์๋ค์๊ฒ ๊ณต์ ๋ฅผ ํด์ฃผ์์ต๋๋ค. - ๋ํ, Front๋ฅผ ๋ด๋นํ๋ ํ์๋ค์ด ์ฌ์ฉํ๊ธฐ ํธ๋ฆฌํ๊ฒ ๋์์ ์ค ์ ์๋๋ก ๊ฐ๊ฐ์ ํ์ผ ๋ณ๋ก ์ด๋ค ํ์ผ์ ์์ ํด์ผ ํ๋์ง ์ ๋ฆฌํ์ฌ ๊ณต์ ํ์ต๋๋ค.
๊ด๋ จ ์ด๋ฏธ์ง
CodeEditor ์์ฑ
codeEditor_Jo.js (line 7)
const codeStarting = document.querySelector('#codeStart')
const codeStarting2 = document.querySelector('#codeStart2')
const texthtml = document.querySelector('#html');
const textcss = document.querySelector('#css');
const textjs = document.querySelector('#js');
const outPut = document.querySelector('#live');
let activeEditor = null;
function createEditor(target, mode) {
return CodeMirror.fromTextArea(target, {
mode: mode,
theme: 'darcula',
lineNumbers: true,
spellcheck: true,
extraKeys: { 'Ctrl-Space': 'autocomplete' },
gutters: ['CodeMirror-linenumbers', 'CodeMirror-foldgutter'],
foldGutter: true,
});
}
let html = null;
let css = null;
let js = null;
function updateOutput() {
const outputHTML = html ? html.getValue() : '';
const outputCSS = css ? css.getValue() : '';
const outputJS = js ? js.getValue() : '';
// HTML, CSS ์ฝ๋๋ฅผ iframe์ body์ ์ถ๊ฐ
outPut.contentWindow.document.body.innerHTML = outputHTML + '<style>' + outputCSS + '</style>';
// JavaScript ์ฝ๋๋ฅผ iframe์ body์ ์ถ๊ฐ
// ์คํฌ๋ฆฝํธ ํ๊ทธ๋ฅผ ์์ฑํ์ฌ ํด๋น ์ฝ๋๋ฅผ ์ถ๊ฐํจ
const scriptElement = document.createElement('script');
scriptElement.textContent = outputJS;
outPut.contentWindow.document.body.appendChild(scriptElement);
}
function setActiveEditor(editor) {
if (activeEditor) {
activeEditor.getWrapperElement().style.display = 'none';
}
if (editor) {
editor.getWrapperElement().style.display = 'block';
editor.refresh();
activeEditor = editor;
}
}
const tabItems = document.querySelectorAll('.tab-container__item');
const contentContainers = document.querySelectorAll('.content-container__content');
tabItems.forEach((item, index) => {
item.addEventListener('click', (e) => {
e.preventDefault();
tabItems.forEach((title) => {
title.classList.remove('active');
});
setActiveEditor(null);
if (index === 0) {
if (!html) {
html = createEditor(texthtml, 'html');
codeStarting.addEventListener('click', updateOutput);
}
setActiveEditor(html);
} else if (index === 1) {
if (!css) {
css = createEditor(textcss, 'text/css');
codeStarting.addEventListener('click', updateOutput);
}
setActiveEditor(css);
} else if (index === 2) {
if (!js) {
js = createEditor(textjs, 'text/javascript');
codeStarting.addEventListener('click', updateOutput);
}
setActiveEditor(js);
}
item.classList.add('active');
contentContainers[index].classList.add('target');
// updateOutput();
});
});
iframe์ ์ฝ๋ ์คํ๊ฒฐ๊ณผ ์ถ๋ ฅํ๋ ํจ์
codeEditor_Jo.js (line 32)
const updateOutput=()=> {
const outputHTML = html ? html.getValue() : '';
const outputCSS = css ? css.getValue() : '';
const outputJS = js ? js.getValue() : '';
// HTML, CSS ์ฝ๋๋ฅผ iframe์ body์ ์ถ๊ฐ
outPut.contentWindow.document.body.innerHTML = outputHTML + '<style>' + outputCSS + '</style>';
// JavaScript ์ฝ๋๋ฅผ iframe์ body์ ์ถ๊ฐ
// ์คํฌ๋ฆฝํธ ํ๊ทธ๋ฅผ ์์ฑํ์ฌ ํด๋น ์ฝ๋๋ฅผ ์ถ๊ฐํจ
const scriptElement = document.createElement('script');
scriptElement.textContent = outputJS;
outPut.contentWindow.document.body.appendChild(scriptElement);
}
CodeEitor.gif
- ์ฌ์ฉ์๊ฐ ์ ์ํ๋ฉด ์ ์ํ ์ฌ์ฉ์์ ํด๋นํ๋ ํญ๊ณผ ์ฒดํฌ๋ฐ์ค๊ฐ ๋ค๋ฅธ ์ธ์์๊ฒ ๋ณด์ฌ์ง๊ฒ ๋๊ณ ,
์ฒดํฌ๋ฐ์ค๋ฅผ ํตํด ์ํ๋ ์ฌ์ฉ์์๊ฒ ์ฝ๋๋ฅผ ์ ์กํ ์ ์๋ ๊ธฐ๋ฅ์ ๊ตฌํํ์ต๋๋ค.
-
์ฌ์ฉ์๊ฐ ๋ฐฉ์ ์ ์ํ ๋, socket.io์์ ์๋์ผ๋ก ๋ถ์ฌํด์ค socketID(๊ณ ์ ๊ฐ)์ ์ฌ์ฉ์ ์ด๋ฆ์ DB์ ์ ์ฅํฉ๋๋ค.
-
์ฌ์ฉ์๊ฐ ์ฝ๋๋ฅผ ์์ฑํ๊ณ , ์ ์กํ๊ณ ์ ํ๋ ์ฌ์ฉ์๋ฅผ ์ฒดํฌํ๊ณ ์ฝ๋ ๋ณด๋ด๊ธฐ๋ฅผ ํด๋ฆญํ๋ฉด
๋จผ์ ์๋ฒ๊ฐ ์ฌ์ฉ์๊ฐ ์ํด์๋ ๋ฐฉ ๋ฒํธ(๊ณ ์ ๊ฐ)์ ์๋ตํด์ค๋๋ค. -
์๋ต๋ฐ์ ๋ฐฉ ๋ฒํธ ๊ฐ๊ณผ ์ฒดํฌํ ์ฌ์ฉ์์ ์ด๋ฆ์ ํฌํจํ์ฌ axios๋ก ๋ผ์ฐํฐ์ ์์ฒญํ๊ณ , ๋ผ์ฐํฐ ๋ด๋ถ์์ DB์ ์ ๊ทผํ์ฌ ํด๋นํ๋ socketID๋ฅผ ์๋ต๋ฐ์ต๋๋ค.
-
์๋ต๋ฐ์ socketID์ ์์ฑํ ์ฝ๋๋ฅผ ๋ค์ ์๋ฒ๋ก ์ ์ก ํฉ๋๋ค.
-
์๋ฒ์์ ํด๋นํ๋ socketID๋ฅผ ๊ฐ์ง ์ฌ์ฉ์์๊ฒ๋ง ์ฝ๋๋ฅผ ์ ์กํ๊ฒ ๋ฉ๋๋ค.
์ฝ๋ ์ ์ก ํด๋ฆญ ๋ก์ง
codeChatList.js (line 227)
// ์ฝ๋ ๋ณด๋ด๊ธฐ ํด๋ฆญ
const codeSend = document.querySelector('#codeSend')
codeSend.addEventListener('click',()=>{
chatSocket.emit('sendClick')
})
chatSocket.on('socketUser',(data)=>{
const checkUser = document.getElementsByName('checkuser')
let myHtml = html ? html.getValue() : '';
let myCss = css ? css.getValue() : '';
let myJs = js ? js.getValue() : '';
checkUser.forEach((user)=>{
if(user.checked == true){
axios.post('/codeChat/userSocket', {name : user.value, roomNum : data.roomNum})
.then(res=>{
let data = JSON.parse(res.data)
chatSocket.emit('codeSendBtn', {html : myHtml, css : myCss, js : myJs, name:user.value, socketId : data.SOCKET_ID})
})
}
})
})
//์ ํํ ์ ์ ์๊ฒ ์ฝ๋ ์ ์ก
chatSocket.on('codeSend',(data)=>{
const tabData = document.querySelector('.tab')
const $tabLang = document.querySelectorAll('.tab-container__item2')
html2.setValue(data.html)
css2.setValue(data.css)
js2.setValue(data.js)
$tabLang.forEach((tab)=>{
tab.addEventListener('click',()=>{
if(tab.dataset.tab == 'tab4'){
html2.setValue(data.html)
}
else if(tab.dataset.tab == 'tab5'){
css2.setValue(data.css)
}
else if(tab.dataset.tab == 'tab6'){
js2.setValue(data.js)
}
})
})
์ฝ๋๋ฅผ ์ ์ก๋ฐ์ ์๋ฒ์ธก ๋ก์ง
server.js (line 287)
// ์ฝ๋ ์ ์ก ํด๋ฆญ ๊ฐ์ง ํ, ํด๋น ๋ฐฉ์ ์ ์ํด์๋ ์ธ์์๊ฒ ๋ฐฉ๋ฒํธ ๊ฐ ์ ์ก
socket.on("sendClick", () => {
ChatNamespace.to(socket.room_number).emit("socketUser", {
roomNum: socket.room_number,
});
});
// ์ฝ๋ ์๋ํฐ ์ฝ๋์ ์ก
socket.on("codeSendBtn", (data) => {
socket.to(data.socketId).emit("codeSend", data);
});
์ฒดํฌ๋ฐ์ค ๊ฐ(์ด๋ฆ)์ผ๋ก DB์์ socketID ๊ฒ์
routes -> codeChat.js (line 181)
router.post('/userSocket',(req,res)=>{
let roomNum = req.body.roomNum
let userName = req.body.name
let sql = 'SELECT * FROM CHAT_USER WHERE ROOM_NUMBER=? AND CONN_USER=?'
conn.connect()
conn.query(sql,[roomNum,userName],(err,result)=>{
if(err){
console.log('select ์ค๋ฅ')
}
else{
console.log('socketID ํฌํจ ๋ฐ์ดํฐ')
res.json(JSON.stringify(result[0]))
}
})
})