요구사항 및 상황 요약
- 동일한 아이디를 이용해서 접속할 때 기존에 같은 아이디를 사용하는 유저의 계정은 바로 튕겨야한다.
- 계정 1개 당 동시에 1명의 유저만 접속가능하다(동일 계정 동시 접속 불가)
- 세션로그인 방식을 이용하고 있다.
- http1.1을 이용하고 있다.
고려사항
1번째 해결법 - web worker, sse (선택)
why service worker & sse??
- 양방향 통신은 필요없고 동일한 아이디로 유저가 로그인 성공되면 다른 클라이언트들에게 해당 아이디가 사용되었으니 지금 쓰고 있는 당신은 사용할 수 없다고 단순 알림만 있으면 된다.
- sse와 worker는 socket보다 구현이 간단하다.
구현 방법 상세 설명
- SSE 설정 및 클라이언트 연결
클라이언트는 SSE를 통해 서버와 연결되어, 서버에서 보내는 알림을 수신합니다.
- 로그인 처리
사용자가 로그인할 때, 서버는 현재 세션 정보를 확인합니다. 동일한 아이디로 이미 접속 중인 사용자가 있는 경우, 기존 세션을 무효화합니다.
서버는 새로운 세션을 생성하고, 로그인 성공 시 해당 정보를 SSE를 통해 모든 관련 클라이언트에게 알립니다.
- 기존 세션 무효화 및 SSE 알림
서버는 새로운 로그인 요청을 처리하면서 동일한 아이디로 접속 중인 클라이언트들에게 SSE를 통해 로그아웃 알림을 보냅니다.
- 클라이언트의 로그아웃 처리
클라이언트는 SSE를 통해 서버로부터 로그아웃 알림을 받으면, 자동으로 쿠키를 삭제하고 로그아웃 처리합니다.
2번째 해결법 - websocket
- 서버와 클라이언트가 동일 아이디가 접속되었는지 안되었는지 확인이 필요 -> 서버와 클라이언트간 통신이 이루어져야함
- 양방향 통신이 그닥 필요가 없다. 서버는 로그인과 해당 아이디가 재로그인되었다는 알림기능만 제공하고 클라이언트는 sse로 받아온 알림을 바탕으로 해당 유저의 현재 쿠키와 세션을 삭제하면되기 때문
sse, web worker 이용시 문제 발생
- php를 서버로 이용하고 있는데 php와 클라이언트가 연결할 때 http1.1을 이용하고 있어 동일한 도메인에 총 6개의 커넥션을 맺을 수 있음
- web Worker가 여러 탭에서 동시에 요청을 보낼 때 문제가 발생했다.
- 커넥션 수는 제한되어 있지만 web worker는 각 탭마다 정보를 공유하지만 각각 따로 커넥션을 맺어서 수행함
- 현재 sse때문에 매번 커넥션을 맺어야함 근데 web worker가 모든 탭에서 커넥션을 각각 맺어버리니 커넥션이 sse연결로만 가득차게됨
- 그래서 req, res를 받을 커넥션이 없어져서 로딩만 돌아감
sse, shared worker로 변경
- web worker의 특징때문에 커넥션 수의 부족이 발생했기때문에 커넥션을 각 탭마다 맺을 필요는 없다고 생각했다.
- 브라우저에서 정보를 공유하니까 하나의 커넥션으로 데이터를 공유하면 되지 않을까?
- shared worker를 쓰자
shared worker는 탭마다 커넥션을 맺는게 아니라 하나의 커넥션으로 정보를 공유한다. 그래서 sse에 할당된 커넥션 하나만으로 다 관리하기 때문에 http1.1을 쓰더라도 sse때문에 커넥션 문제가 발생하진 않는다.
이렇게 shared worker와 sse를 이용해서 동시접속을 막아보았다.
느낀점
기존에 동시접속 제한? 동일한 아이디로 접속 시 기존 유저 팅기기 이런 생각은 전혀 해본적이 없었다. 왜 그런지 순간적으로 깨달았다. 보통은 각자 자기 아이디를 가지고 다른 사람들에게 알려주지않아서 동일한 아이디로 접속이란걸 생각해본적이 없었던 것이다. 진짜 그래서 뭔가 어색한데 뭐지?라고 느꼈던 것 같다.
이거 때문에 worker도 공부하고 색다른 경험이었다.