[소켓 서버] 소켓 연습용 지뢰찾기 게임 멀티 만들기
프로그래밍 언어 및 기타/Spring Boot

[소켓 서버] 소켓 연습용 지뢰찾기 게임 멀티 만들기

https://github.com/sglee487/isolia/blob/f3ed6eef3c61d689322dbd2173f698a4266d2be5/src/mores/MineSweeper.vue

 

GitHub - sglee487/isolia: https://isolia.shop/

https://isolia.shop/. Contribute to sglee487/isolia development by creating an account on GitHub.

github.com

https://github.com/sglee487/isolia-spring-api/blob/e1048f811a0c76723b19a21dc22b95aa522d075a/src/main/kotlin/com/group/isolia_api/controller/MineSweeperController.kt

 

 

GitHub - sglee487/isolia-spring-api: change FastAPI to Spring boot

change FastAPI to Spring boot. Contribute to sglee487/isolia-spring-api development by creating an account on GitHub.

github.com

 

만들 생각이 없었는데... spring boot를 nginx서버로 배포할 때 자바 어쩌구 하길래 배포는 해 봐야 공부될 것 같아서 만들었다.

 

소켓 설정인데 중요한건 맨 밑의 CustomHandshakeHandler다. 각 소켓에 고유 아이디 부여해서 이걸 session id로 취급하기로 했다.

왜냐? SimpleMessagingTemplate.convertAndSendToUser에서 seesionid를 아무리 넣어도 client가 못받아들이기 때문에, 그냥 저걸 만들어서 사용하기로 했다.

 

이래도 안돼?? 이야~~ 독하다 독해 ㅋㅋㅋㅋ

 

그리고 어차피 convertAndSendToUser로 들어가도 결국은 convertAndSend에서 이름만 추가해서 보내지는 방식

 

spring boot에서는 socket를 STOMP라는 것을 통해 한다고 한다. 쌩 socket은 진짜 메세지만 주고받기 때문에 얘내를 간편하게 해주는 도구 socket.io가 있는데 얘도 비슷한 거인듯.

서버에서 설정해 준 uuid 이름은 header의 user-name으로 오더라. 그래서 이걸 client가 저장해서 서버에 자신이 누군인지 같이 보내 알려준다. 나머지 subscribe들은 서버에서 설정해준 대로 따라가면 됨.

 

일단 접속하는거 부터 살펴보면 일단 접속한 뒤에 맨 밑줄에 send('/publish-mine/join')을 보낸다. 왜 이러냐면 나도 연결할 때 개인 구독(stompClient.subscribe(`/subscribe-mine/user/${username}/start`)을 통해 바로 게임 진행 상황을 받고 싶었는데, 연결이 되고 나서 구독을 정의할 수 있게 되어있다.

onSessionConnected로 연결이 되면 해당 플레이어의 이름과 색을 만들고 sessionid을 키로하는 딕셔너리를 만든다. 그래서 접속하면 /subscribe-mine/players로 이 플레이어가 접속했다는 상황을 알리고 막 접속한 플레이어한테만 해당 게임 상황을 알린다. 물론 연결이 끊어졌을 때의 함수 onSessionDisconnect으로 연결 해제시 해당 플레이어를 삭제한다.

이때 신기한건 그냥 다짜고짜 onSessionConneted를 했는데 알아서 socket의 연결임을 알고 잘 한다. 이 정도되면 좀 무섭다.

 

그 다음은 지뢰찾기 판에서 각각의 칸에 클릭과 오른쪽마우스 클릭(contextmenu)이벤트를 넣어준다. 해당 칸을 클릭했을 시, 행동 종류(reveal, flag)와 자신의 이름, 칸 위치가 보내진다.

 

그럼 서버에서 session id와 해당 플레이어의 색, 이름의 정보를 쌍으로 저장하고 있다가 이를 이용해서 구분, 데이터베이스에 기록하고 action을 구독하고 있는 client들에게 "이런 액션이 발생했어요~~" 하고 보낸다.

 

그럼 구독하고 있는 client가 상황에 따라 적절한 행동을 취한다.

 

 

사실 이게 전부다. 나머지는 뭐 코드 정리하고 반환 좀 다르게 해주고.. 하는 부가적인 것들이라..

위 코드를 string을 알아서 json으로 바꿔주는 기능이 있다는 것과 확장함수를 활용해서 간단하게 만들 수 있다. 하니까 되서 나도 놀랐다.

 

원래 Pair로 저장한걸 그대로 보내서 client는 좌표와 상관없이 뜬금없는 first, second를 받았다.

프론트에게 시비걸리지 않게 x,y를 내보내도록 바꾼다.

 

 

 

 

그리고 이정도면... 진짜 spring boot 프레임워크가 얼마나 잘 되어있는지 알게 되었다. 기존에 썼던 FastAPI는 socket.io도 지원이 안되는 수준이라 쌩 websocket으로 구현했어야 했고 작동 방식이 서브프로세스들 생성하는 방식이라 얘내들끼리 소통하는것도 관리해주었어야 해서 죽을맛이었다.

 

 

파이썬 맛 좀 볼래?? 아뇨...