수요일(2012-04-25) 오후에 있었던 이승재 군의 발표.
발표 자료는 http://ricanet.com/new/view.php?id=blog/120425 에서.
HTTP Protocol의 한계
http는 request/response protocol이다. 이로 인해서 클라이언트 쪽의 이벤트는
서버 쪽에 쉽게 전달할 수 있지만, 서버 쪽의 이벤트는 클라이언트가 요청하기
전에는 전달할 수 없다.
그런데 현재의 웹 쪽 트렌드를 보자면, twitter나 facebook, google mail (or talk)
같은 경우 실시간으로 메시지를 보낸다. 어떻게 하는걸까?
이를 극복하기 위한 기법들
기본적으로 꼼수다 — 프로토콜의 한계 때문에.
Polling
웹 브라우저에서 주기적으로 요청을 보낸다. (클라이언트 쪽 타이머 이용)
문제:
- 트래픽이 많다 / 서버 쪽 부하가 걸린다
- 지연 시간이 크다; 이벤트-클라이언트 요청 시간 차이 때문에. 그렇다고지연 시간을 줄이면 트래픽/서버 부하가 더 커진다.
Long-polling
클라이언트가 미리 요청을 보내고, 서버는 이벤트가 생기는 순간까지 기다렸다가
이를 모아서 (이미 온 요청에) 응답을 보낸다.
Facebook 메신저 구현이 이를 이용한다.
문제:
- 구현 복잡도. 서버가 요청이 이미 와 있는 경우와 그렇지 않은 경우를 구분해서 처리해야하는 등.
- 지연 시간; 응답을 보낸 후 클라이언트가 다시 요청을 보내올 때까지의 시차.
Hidden iframe
페이지에 숨겨 놓은 iframe을 통해서 메시지를 계속 흘려 보낸다. (서버가 응답을
끝내지 않는다) 그래서 http streaming이라고 부르기도 한다.
Gmail messenger(=google talk)에서 사용하는 방법이다.
문제:
- 응답이 끝나지 않기 때문에 클라이언트 쪽 웹 브라우저에 메모리 릭이 생긴다.
- 프록시 / 보안 프로그램이 응답이 완전히 끝나야만 이를 넘겨주는 경우가 있다.
Browser plugin
Flash, ActiveX 등을 이용. 사실 상 TCP 소켓처럼 쓸 수 있다.
호환성 문제가 너무 커서…
WebSocket (html5)
javascript 단에서 진짜 소켓을 쓸 수 있다. 표준화가 아직이라 (protocol은
결정되었지만, API가 아직 unstable).
기존 웹브라우저와의 호환성 문제.
WebIRC (=IRC web-bridge for smartphones) 만들기
Long-polling이 호환성이 좋고 (최소한 iOS, android를 지원해야 했음),
구현이 재밌어 보여서(…) 이를 구현함.
프로토콜
- InitLog: 각 채널 최근 로그 k 줄을 요청
- UpdateLog(last\[\]): 각 채널에서내가 마지막으로 받은 로그 ID가 last일 때 그 이후 로그를 요청
서버 구현 이슈
HTTP 핸들러가 새로운 내용이 없으면 대기하는 것.
vs.
Event listener가 새로운 내용이 왔을 때 대기 중인 스레드(의 요청)를 깨우는 것
사이의 레이스 컨디션.[1]
node.js 류를 사용하면 오히려 쉬웠을지도 모르지만 이미 python으로 구현.
Webserver Architecture
동시에 살아있는 연결이 많아서,
- 커넥션 당 1 스레드 때문에 메모리 병목
- 고전적인 웹 서버의 경우 더 중요한 페이지 뷰보다 동시 접속 수가 문제
- Gevent로 쉽게 해결
- Long-polling에 맞춰서 구현했더니 stateless 프로토콜이 되어 네트워크 단절에 강해졌다.
- 채팅 보내는 것이 네트워크 불안정엔 약했음. 이걸 극복하려니 사실상 TCP 류의 프로토콜을 HTTP 위에 재구현하는 형태가 되어버리게 되서…
Middlewares
앞에서 언급한 방법들엔 정답이 없다. 각 방법의 장단점이 다름.
orbited2, socket.io 같은 미들웨어가 있다.
그렇지만 정작 제작 시점에 사용하려던 orbited 사이트가 내려가 있어서
long-polling을 직접 구현.
Orbited
orbited.js + *application.js* — orbited server — application server
위의 형태로 구성. Web-router + firewall의 역할. Legacy TCP 응용프로그램
서버인 경우에도 쉽게 통신할 수 있다.
socket.io
nopde.js 기반. 메시지 단위 전송을 지원한다.
확인해야 할 사항
- 연결 당 서버 리소스 소모량
- 연결이 불안정하면 어떻게 되는가?
- 웹 브라우저를 껐다켜도 괜찮은가?
웹-게임 연동
이런 기술을 쓰면 웹 게임에서도 네트워크 제약(http 문제)이 *거의* 없어진다.
WoW 전정실, 아이온, 마비의 거래소, 넥슨 홈이나 스팀의 업적 시스템 구현이라거나,
게임 웹 채팅, 친구 게임 참여 알리기, 우편 도착 알림 등의 실시간 기능이 가능해질듯.
결론(?): 취미 프로젝트 좋아요(…)
- 내 생각, 그리고 최치선 군의 의견을 조합하자면, 저건 pthread condvar 류의 동기화 도구를 사용하면 해결 될듯 함. 치선 군이 실 서비스에서 사용하고 있는 추천 구현체는 gevent의 Queue (monkey-patching하는). [↩]
`감상’은 업무 시간 끝나고나면(…)
암호화 어쩔 …
아.. 암호화 얘기 안 했네요.
저희는 그냥 롱 폴링을 https 써서 했습니다 :]
https도 사실상 암호화 안된거나 다름없다는게 문제가 되지 않을까요…
PC에선 텍스트로 다 보이니 ..
https는 SSL 설정만 제대로 되어있다면 충분히 강력합니다.
암호화 채널의 양쪽 끝에서 암호화가 풀리지 않으면 좀 곤란하지 않을까요 (…)
물론 암호화를 당연히 해제 할 수 있어야 하지만…
Fiddler같은 HTTPS 스니퍼의 존재로 인해 아무런 전문지식이 없어도 보고 변조가 가능하다는게 …
보안 쪽엔 문외한이라 속단하진 못하겠지만, https MITM 공격이 그렇게 쉽게 되진 않는데요.
Fiddler로 스니핑을 하는건 CA cert를 속일 수 있거나 / 브라우저 류의 보안 부분을 잘 눌러놓거나 정도 밖에 없지 않나요?
아… 이거 발표하신분이 웹쉐어 만드셧던 분이구나….
부럽다 넥슨 ㅡ,.ㅡ
WebShare 제작자들은 N모사 들에 골고루 퍼져있습니다만 (…). 벤쳐에도 있지만 (…)
음 그렇군요 ….
저도 주로 꼼수를 사용하고 있는데 여기서 설명하는 polling, long-polling 기법인 듯 하네요. 머리 굴려서 열심히 만들었는데 결국 사람 생각하는거 다 거기서 거기 ㅋㅋ 이거랑 push notification server를 이용하면.. 어느정도 해결이 되더라구요.
html5를 쓰거나 사도(?)에 해당할 만한 플러그인을 쓰지 않는한 가능한 범위가 거기서 거기니까 ㅋ