KENTECH 친구 부탁으로 간단한 웹사이트를 만들어봤다.
사실 내가 재밌어보여서 뺏어와서 만들어버린거긴 한데
간단히 소개를 하자면 집단 동기화를 실험하기 위한 프로그램이다. 아래 링크와 관련된 연구?를 하기 위한 프로그램이라던데 무슨 연구인지 자세히는 모른다 ㅋㅋㅋㅋ
https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=open_kbsi&logNo=221334772489
옆 사람의 박수를 따라 치는 과학적인 이유
공연이 끝나고 난 뒤, 관객들은 훌륭한 공연에 대한 답례로 열광...
blog.naver.com
버튼을 누르면 box(칸)가 깜빡이는 것으로 박수를 표현하였다.
동시에 여러 명의 사람들이 접속해서 각자 버튼을 눌렀을 때, board에 있는 box들 중 자신의 box가 깜빡인다. 그리고 그 깜빡임이 다른 사람들의 화면에도 표시되도록 해야한다. 즉, 자신 뿐만 아니라 다른 사람들이 버튼을 누르는 것(박수 치는 것)도 표시되어야한다.
이것을 구현하기 위해서, WebSocket을 활용하였다. 웹소켓은 서버와 클라이언트가 실시간으로 양방향 통신할 수 있게끔 해주는 통신 프로토콜이다.
사실 나도 잘 모른다. 오늘 이거 만들면서 처음 써봤다.
directory 구조는 다음과 같다.
socket.js가 client, app.js가 server code다.
package.json 파일은 실행에 필요한 여러 모듈들에 대한 정보를 담은 파일이다.
cmd에서 directory 들어가서 npm install 명령어 실행하면 다운된다.
public 폴더로 묶은건 코드들을 분류하기 위함인데,
코드들은 public과 src(source) 폴더로 구분하며
public에는 application을 컴파일 할 때 사용되지 않는 코드들이,
src에는 컴파일 할 때 사용되는 코드들이 들어간다.(ex app.js)
app.js
const express = require('express');
const app = express();
const http = require('http');
const path = require('path');
const server = http.createServer(app);
const socketIO = require('socket.io');
const io = socketIO(server);
const PORT = 5000; //localhost:5000
app.use(express.static(path.join(__dirname, 'public')));
var idArr = new Array(31);
for(var i=0 ; i<31 ; i++){ //box_id 배열 초기화
idArr[i] = 0;
}
function findId(){ //비어있는, 사용중이지 않은 box 중 가장 작은 id 값 탐색
for(var i=1 ; i<31 ; i++){
if(idArr[i] == 0) return i; //0이면 비어있는 box
}
return -1; //유저 최대 수용 수인 30을 넘어간 경우
}
io.on("connection", (socket)=>{ //웹소켓 연결 성공
var id = findId();
if(id < 0){
socket.emit("id", id);
socket.disconnect();
}
idArr[id] = 1;
socket.emit("id", id);
socket.on("clap", (data) => { //누군가 박수를 쳤을 때, 모든 유저의 화면 업데이트(깜박이게)
const d = new Date();
var text = d.toLocaleTimeString();
console.log(text + ", id:", +data);
io.emit("update", data);
});
socket.on("disconnect", ()=>{ //유저가 창을 닫은 경우, box 초기화
idArr[id] = 0;
});
});;
server.listen(PORT, () => {
console.log(`Server ${PORT}`);
});
socket.js
const socket = io('http://localhost:5000');
var button_id = 0;
socket.on("id", (data) => { //올바른 box를 배정 받았는지 확인
if(data < 0){
alert("Can not JOIN! It's FULL");
}
else{
button_id = data;
document.querySelector('p').innerHTML = "Box ID = " + data; //배정 받은 box의 id표시
}
});
clapButton = document.querySelector('.clap'); //버튼 클릭시 서버에 update 요청
clapButton.addEventListener("click", () => {
socket.emit('clap', button_id);
})
socket.on("update", (data) => { //클릭된 버튼의 box를 깜빡이게끔 html code 수정
var box = document.querySelector(`#b${data} `);
if(box.className == 'box'){
box.setAttribute("class", "changedBox");
setTimeout(() => {box.setAttribute("class", "box");}, 200);
}
})
node app.js 로 실행해보면 아래처럼 잘 된다.
여러 명이 동시에 버튼을 눌러서 board에 여러 box가 깜빡거리는 화면을 보여주고 싶지만, 조작할 수 있는 마우스가 1개라서 아쉬울 따름이다.(진짜 됨)
나중에 친구한테 30명이 동시에 접속했을 때의 실행 화면 캡쳐를 받아서 업로드 해야겠다.
추가로 친구가 누가(어떤 box id) 언제 버튼을 클릭했는지에 관한 데이터가 연구 과정에 필요하다고 해서, console.log로 출력되게 했다.
코드 넘겨주고 과외하러 가던 중에, 친구한테 밀리초까지 표시되게 할 수 없냐고 연락이 왔다.
과외 끝나고 집에 와서 코드를 살짝 수정해줬고, 아래처럼 시간이 밀리초로 나오게 된다.
아직 수정된 코드는 안줬다. 사실 줄 생각이 없다 ㅋㅋㅋㅋㅋㅋㅋㅋ
진짜 코드 한 줄만 바꿔주면 된다.
구현 과정에서 가장 어려웠던 점은
유저가 브라우저를 닫았을 때, 몇 번째 box를 배정 받은 유저가 연결을 끊은 것인지 확인하고 다른 유저가 새롭게 배정 받을 수 있게끔 하는 것이었다.
원래는 window.onbeforeunload 를 활용하려 했었는데, 크롬에서는 안되고 firefox에서만 되는 것으로 보였다. 크롬에서 저 함수를 보안상의 이유로 막아놓은 것 같다.
2시간 가까이 방법을 강구하다 찾아낸 것이 웹소켓에서 바로 처리하는 것이었다. 유저가 브라우저를 닫으면, 자동으로 웹소켓 연결은 끊어지기 때문에 app.js에서 연결이 disconnect 될 때 id 배열 값을 0으로 초기화해줬다.
성공했을 때 정말 기뻤는데 생각보다 너무 간단하게 끝나서 시무룩하기도 했다.
뭔가 직접 필요한 코드를 짜고, 프로그램을 만든다는 건 참 재밌는 것 같다.
2023 1학기 인터넷프로그래밍 수업에서 php를 활용해서 게시판을 구현해 봤었는데,
연습할겸 조만간 게시판도 다시 한번 만들어봐야겠다. php 안쓰고 javascript로도 구현해봐야겠다.
이제 Data Forwarding과 Hazard Detection이 가능한 MIPS Pipelined CPU를 구현하러 가야한다.
영교수님의 컴퓨터아키텍쳐는 너무하다. 옆 집 이컴아는 과제도 시험도 쉽다는데 영컴아는 왜이러노
어떻게 종강이 6월 26일? 어떻게 종강이 6월 26일? 어떻게 종강이 6월 26일? 어떻게 종강이 6월 26일?
'diary' 카테고리의 다른 글
Architecture of Computer Assignment 4. Improving the Pipelined CPU (0) | 2023.06.25 |
---|---|
기록 시작 (4) | 2023.06.23 |