(장준영)Vanilla JavaScript로 SPA 구현하기 [8일차] - 식당/카페 여석 확인 어플리케이션

2024. 4. 18. 03:31프로젝트 일지

사용자가 매장 입장 후의 화면을 다 만들었다, 이제 매장 나가기 버튼 처리를 좀 해주고

캐싱된 데이터로 렌더링을 할거다

나가기 버튼은 매장에서 나가는거기때문에, 나가면서 store_user 컬렉션의 요청.user 가 속해있는 도큐면트를 삭제하고

나가야한다, 추가적인 캐싱은 안 해줘도 된다, 어차피 다른 매장에 입장하면 로컬스토리지가 업데이트 된다

매장 나가기를 클릭하면 서버쪽으로 post 보내서 그냥 삭제만 해주면 된다

서버쪽도 코딩해주자

매장 나가기 기능도 잘 작동한다

이제 캐싱된 데이터 대로 렌더링만 해주면 끝!

 

지금 새벽 3시 반이다 나머지는 자고 일어나서 내일 해줘야겠다 !!

 

자고 일어났다, 다시 작업을 시작하자..! 

작업 하다보니 디비 잘못 짠 부분이 또 있다, 캐싱해서 렌더링 해줄땐 필요한 데이터를 그대로 가져와야하지, 필요한 데이터에 접근할 수 있는걸 가져오면 불편하다,

점령자와, 낙오자에 유저 이름을 가져다 넣어야하는데 유저의 id로 유저이름에 접근하겠다고 생각했다, 

몽고db는 몽고db의 사용법을 따라야할거같다, 다 이유가 있는법이니까

 

이번 프로젝트가 끝나고 몽고db 에 대해서도 공부해야겠다

 

일단 디비에 들어가는 값을 유저 아이디가 아닌 유저 네임으로 다시 짜주자

서버쪽 코드만 수정해주면 된다

이제 다시 렌더링 해주자

문제가 또 발생했는데.. 위 코드에서 findOne 으로 하면 유저 한명밖에 못 가져온다 find().toAraay() 를 해줘야한다.. ㅠㅠ

접속자들도 다 잘 렌더링된다, 근데 최신 정보를 받아오려면 당연하게도 매장에서 나갔다가 다시 들어와야하는데

이건 소캣통신 배워서 어떻게 처리를 해볼 생각이다, 우선 소캣처리 배우기 전 까지의 준비를 오늘 오후 6시쯤? 전엔 끝내놓을 생각이다 

 

소켓으로 어떻게 뭐 하기 좀 그러면, ...

1분마다 실시간으로 데이터 받아와서 렌더링해줄까 싶기도하다, 셋인터벌로.. ㅋㅋㅋㅋㅋㅋ 

어떻게든 방법은 있으니, 일단 하자

우선 사용자 렌더링 코드를 작성하는 김에, 자리주인 렌더링 코드도 작성해주었다

 

자리 주인은, 매장 자리를 눌러서 결정되는거기때문에, 의자를 클릭해서 서버로 자리 점령 요청자의 이름과 가게이름 자리번호에대한 정보를 보내고, 서버에서는 

자리주인 컬렉션 인서트 해주고, 자리주인, 매장이용자, 매장에대한 데이터를 다시 받아서 클라이언트쪽에 보내주고

클라이언트에서 다시 캐싱 후 다시 렌더링 해주면 될거같다, 음.. 그리고 자리주인이 매장에서 나갈땐

그냥 매장 나가기 누르면 처리할때, 캐싱된 자리주인 데이터에 자기이름도 있는경우 없는경우에 따라서 매장에서 나가는 post 요청 로직을 다르게 해주면 될 거 같고..

 

나머지는 밥 먹고와서 하자 ^^

 

치킨먹고왔다

일단 서버쪽 코드 작성해주고

이제 클라이언트에서 데이터 다시 캐싱하고 다시 렌더링 하면 되는데, 렌더링은 그냥 화면생성기()한번 호출하면 끝이다

클라이언트쪽 코드 작성했고, 이제 실험해보자

아 또 실수한게 ㅋㅋㅋ 겟엘리먼트바이클래스() 를 써야하는데 겟엘리먼트바이아이디 를 썻다, 빠르게 코딩한다고

자동완성 막쓰다보니, 자꾸 이런일이 있지만,, 뭐 디버깅하는데 1분도 안 걸리니 걱정은 없다

점령자 리스트에 렌더링 하는건 했고, 이제 후처리로

점령된 의자 렌더링 해주고, 이미 자리 선택했으면 다른자리 선택 못하도록 막아주면 된다

렌더링과 자리선택 막는 방법은 로컬스토리지에 있는 자리주인 배열에 내 이름이 포함돼 있으면

그 자리는 다르게 렌더링 해주고, 더이상 선택 안 되게 해주면 되긴한데, 지금 브라우저 상에 내가 누구인지에 대한 정보가 없어서, 서버에서 처리해줄까 싶다, 자리 선택 부분은 안전해야해서, 서버에서 처리해주기로 하자

 

자리 여러게 못하게 막는방법은

서버에서 자리주인 컬렉션에 요청.user.username이 존재한다면 응답.json() 으로 그냥 요청 씹어버리고

 

주인있는 자리 다르게 렌더링 해주는건 다시 생각해보니

내가 누구인지 딱히 알 필요는 없다, 그냥 자리 렌더링할떄 이 자리번호가 로컬스토리지의 자리주인 데이터에 있는 자리번호에 있는지 검사해서 있으면 다르게 없으면 그냥 출력 해주면 된다

 

일단 서버쪽부터 코딩해주자

이렇게 하면 자리는 중복해서 앉을 수 없다

 

이제 자리 다르게 렌더링 해주고 매장 나가는 로직 만들어주자

 

아 그리고 이미있는자리 다른사람이 선택 못하게하는건 하면 안된다, 게임 요청을 해야해서..

그래서 서버쪽에서 나중에 후처리로

자리주인이름이랑 요청.user.유저네임이 다른 경우에는 게임신청 걸도록 해줘야한다

 

암튼 자리 렌더링 해주자

 

디버깅하다 알게됐는데

배열에서 includes() 를 사용해서 같은값이 있는지 찾을때

taked_chair_number_list = ["2"] 라서 그냥 i 를 넣어도 자바스크립트 답게 

"2" 를 2 라고 알아서 바꿔서 i랑 비교해줄지 알았는데, 코드가 정상작동을 안 하길래

Number()을 사용해서 "2"를 2로 직접 바꿔주니 정상작동을 했다

자바스크립트에서 indclude() 를 사용할때 타입까지 일치해야하는건가? 싶었다, 프로젝트 끝나고 좀 더 알아봐야겠다

화면상 렌더링이 문제없이 잘 작동하는데

 

오류가 하나 있다, 내가 자리 번호 넘버링을 1부터 하고싶어서 반복문의 i를 이용해 i+1 로 넘버링을 했는데 

서버쪽으로 자리번호를 보낼때도 i를 사용했어서 화면 상으로는 3번 자리를 점령한거지만, 디비상으로는 2번 자리를 점령한거기때문에 이거때매 문제가 나중에 발생하지않을까? 라는 생각이 든다..

 

일단, 큰 문제는 안 생길거같기때문에 그 문제는 발생하면 해결하도록하자,

이제 매장에서 나가면 점령한 자리에서도 나가지는거만 만들어주면 된다 

 

매장에서 나가면 서버쪽에서 요청.user.유저네임을 유저네임으로 가지고있는 도큐먼트들

자리주인 컬렉션에 있는 도큐먼트

스토어유저 컬렉션에 있는 도큐먼트

를 딜리트 해주면 끝이다

 

코딩은 담배한대 쪽! 빨고와서 하자

한대 쪽 빨고 쫌 쉬다왔다 4시 정각인데 뭐 오늘 생각해놨던 6시 내로는  다 끝날거같다

아 근데 세션 만료 시간을 1시간 으로 해뒀더니 쫌만 쉬고와도 세션이 만료되네.. 세션 시간좀 늘려야겠다

세션 만료시간 2시간으로 늘리고왔고

 

이제 본격적으로 매장 나가기 코딩해주자

 

근데 갑자기 드는생각인데 

게임 꼭 소켓으로 안 해도 될거같은데??

그냥 게임 요청 날리면

요청 받는 유저한테 응답.sendFile(game.html) 날리면 되는거 아님??

이건 일단 매장 나가기 코딩 끝나고 생각해봐야겠다

그냥 너무 간단하다 뭐... 뭐 없다

 

아 그리고 이거 하나만 더 해주자

자리 점령하면 낙오자에서 내이름 빠지는 거로 렌더링하는 코딩만 해주고 이제 좀 쉬다가

게임만들기만 하면 된다

 

낙오자에서 내 이름 빠지는건 렌더링할때

채어오너.유저네임.인클루드() 으로 점령한 자리가 있는 애들을 빼고 낙오자로 렌더링 시킬거다

그냥 이렇게 코딩해주면

잘 작동한다 ^^

몇번자리 점령자인지에 대한 정보도 주었다

아 그리고

이렇게 렌더링할때 자리 주인이 있는 자리는 처음부터 이벤트리스너를 안 달아주고 렌더링해주는거라 

자동으로 이미 있는 자리는 점령이 불가능하다

음.. 이제 뭐 ㄹㅇ 더 할건 없다

 

지금은 4시 20분 쯤인데, 6시까지 하려했던건 다 끝냈다

 

원레는 소켓io 같은거 써서 실시간 끗말잇기 맞짱 할라그랬는데

시간이 좀 남아서, 소캣io같은거 안 쓰고 하는법 생각해봐야겠다

 

일단 내가 어떤 유저한테 영향을 주려면 일단 서버한테 시켜야하는데

서버로 요청을 보내고싶은 유저의 정보를 주고

서버에서 처리를 시작할텐데..

서버에서 어떤유저를 특정, 지정 한 뒤에 그 유저에게 응답을 보내는 방법이 절대 없진 않을거다

그 방법을 일단 찾아보자

 

음,.. 일단 실시간 데이터 전송이 어떻게 구현되는지, 그 원리를 알아야할거같다

그 원리를 먼저 찾아보자, 뤼튼한테 물어봐야겠다

뤼튼이 그냥 닥치고 소켓 라이브러리 쳐 쓰라고 했다 ^^

 

하지만 !!!

학교가 6시에 끝나는데 2시간동안 뭘 할게 없다, 심심하니 소켓 통신은 어떤 원리로 하는건지 공부나 해야겠다

이따 집 가서 또 글을 작성해야겠다

 

집에 와서 소켓.io 사용법 까지 익혔고 이제

게임을 위해 게임방을 만들어줘야한다

점령자에게 자리빵 신청하기 버튼을 통해 가장 오른쪽의 자리걸고 맞짱한판 ㄱ 에 게임방을 만들어줄거다

자리빵 신청은 낙오자만 할 수 있기 때문에, 자리빵 신청을 보내면 서버로 어떤 점령자에게 자리빵 신청을 걸었는지

점령자의 이름이 전송되고 아래의 경우를 모두 만족할 경우 게임방이 생성된다

1. 게임방 컬렉션에 신청이 걸린 점령자의 이름이 포함된 게임방이 없는 경우 = 이미 자리빵 신청이 걸린 경우

2. 자리빵이 벌어질 매장의 점령자에 요청.user.유저네임이 포함되지 않은 경우 = 점령자는 자리빵을 걸 수 없음

 

그리고 낙오자가 자리빵 신청을 하면 해당 매장에 전체 알림이 간다, 누가 누구에게 자리빵 신청을 했다고

이를 위해서 매장에 입장하면, 해당 매장을 룸으로 가지는 소켓이 만들어지게 하고 그 룸에

누가 누구에게 자리빵 신청을 했다는 방송이 울려퍼진다, 그리고 동시에 모든 유저가 화면을 다시 렌더링하게 하면

자리걸고 맞짱한판 ㄱ에 게임방이 만들어져있을거다, 10초 내에 게임 요청을 안 받으면, 게임 요청을 받은사람은 

자동으로 자리에서 낙오된다

 

일단 항상 뭐든

작은것부터 하나하나 차근차근 하다보면 다 만들어져있다

하나하나 시작해보자 

일단 게임장 디비에 게임 도큐먼트 만드는거부터 시작하자

자리빵 신청하기 버튼을 누르면 서버로, 매장의 이름, 수락자 이름, 제시어가 전송되고

서버에서 개임방 도큐먼트를 게임방이름 : ...

게임방 이름을 고유한 값으로 해야하는데, 어떻게든 방법이 있겠지만 

시간이 얼마 없음으로..게임방 이름은 수락자이름+VS+요청.user.유저네임 이 될거다 

 

다시 정리해보자면 

자리빵 신청하기 버튼을 누르면 서버로 수락자 이름, 제시어가 서버로 전송되고

서버에서

1. 게임방 컬렉션에 신청이 걸린 점령자의 이름이 포함된 게임방이 없는 경우 = 이미 자리빵 신청이 걸린 경우

2. 자리빵이 벌어질 매장의 점령자에 요청.user.유저네임이 포함되지 않은 경우 = 점령자는 자리빵을 걸 수 없음

위 조건을 모두 만족하는 경우에 게임방 도큐먼트를

게임방이름 : 수락자이름+VS+요청.user.유저네임

요청자이름 : 요청.user.유저네임

수락자이름 : 수락자이름

제시어 : 제시어

로 만들어주고 

게임방 컬렉션중에 요청자이름 or 수락자이름 이 요청.user.유저네임 인 도큐먼트들을 긁어서 

화면렌더링을 위해 필요한 데이터들과 함깨 담아 제이슨으로 클라이언트로 보내줄거고

글라이언트에서 캐싱 후 화면에 렌더링해줄거다

 

게임이 끝나면 게임방과 게임내용에 관한 데이터는 다 삭제시켜버리면 되니까

다른게임 중복의 경우는 생각하지말자 

서버쪽은 이렇게 코딩해주면 된다, 다시 렌더링해야할때 자리걸고 맞짱한판 ㄱ 에있는 데이터도 렌더링 해야해서

다시 렌더링을 하기 위해 필요한 데이터를 클라이언트쪽으로 보내주는 api들을 수정하느라 좀 많이 귀찮았다

문제없이 정상작동한다

실험좀 해보자, 이런 저런 경우 실험좀 해봤는데 잘 작동한다

내가 점령중일때 자리빵 신청 안 되고, 현재 자리빵중인 점령자에게 자리빵을 신청할 수 없다

 

자 이제 자리빵 버튼 클릭하면

게임으로 이동하는거로 하자

일단 끝말잇기 전에 

게임 내에서 실시간 채팅기능을 만들고 그 기능을 끝말잇기 게임으로 발전시키는 방향으로 가야겠다

 

자리빵 버튼으로 게임시작하는건 ssr로 game.ejs 렌더링 해줄거고

그 안에서 소켓io를 사용해서 실시간 채팅이 이루어지도록 만들거다 

 

하.. 씨~ 이발 벌써 새벽 4시 14분이다, 담배한대 쪼옥 빨아주고 시작해야겠다

아 근데 안 자면 머리 안 돌아간다 그냥 자고 내일 해버리자

 

일어나니까 오전 11시다 오늘 오후 4시 프로젝트 발표가 있으니

6시간 남았다 ㅋㅋㅋㅋ 어서 만들자

 

일단 자리빵 버튼 클릭하면 게임방으로 이동하는 거 부터 해보자

클라이언트에서 버튼을 누르면 서버쪽으로 해당 게임룸의 이름이 보내지고,

서버에서는 게임룸의 이름을 받아서 해당하는 이름의 게임의 데이터를 이용해 .ejs를 렌더링해주면 된다

 

채팅은 그냥 블로그에 안 쓰고 개빨리 만들었다 바빠서

그리고 30초마다 그냥 매장 정보 새로받아와서 재랜더링 해주는거 셋인터벌로 만들어줘야겠다

이렇게 코딩했다, 발표시간이 4시에서 2시로 갑자기 앞당겨졌다, 그리고 지금은 1시 50분

ㅋㅋㅋㅋㅋㅋㅋ 음 뭐 발표가 가능하긴 할거같다

끝말잇기 로직은 완성못했지만...

 

이번 프로젝트는 용두사미 같다

처음만 거창했지.. 시간이 부족한게 아니라, 삽질을 많이 한 편? 인거같다, 

8일 중에 거의4~5일을 기획만 했는데, 웹 사이트를 만드는것은 처음이라, 기획도 실패했고.. 음 그래도 

이런 경험들이 쌓이고 배워서 이런점을 보완할 수 있지 않겠나?