2014-03-03 5 views
3

Clojure에서 확장 가능한 채팅 서버를 구축하려고합니다. http-kit, compojure 및 redis pub/sub를 사용하여 다른 노드 사이에서 통신합니다 (팬 아웃 방식). 서버는 연결 b/w 클라이언트 - 서버에 긴 폴링 폴백을 사용하여 웹 소켓을 사용합니다. 단일 사용자는 브라우저의 탭마다 하나의 연결로 여러 개의 연결을 가질 수 있으며 메시지는 모든 연결에 전달되어야합니다. 가 Clojure의 확장 가능한 채팅 서버. 존재 및 메시지 도착 및 재 연결과 관련된 문제

그래서, 기본적으로 사용자 I 메시지는 WebSocket을 긴 폴링 채널 모두를위한 공통 경로에 게시

{:userid1 [{:socketuuid "random uuid#1 for uerid1" :socket "channel#1 for userid1"} 
      {:socketuuid "random uuid#2" :socket "channel#2"}] 
:userid2 [{:socketuuid "random uuid#1 for userid2" :socket "channel#1 for userid2}]} 

으로 랜덤 UUID를 갖는 원자에 상기 채널 저장 연결할 때 메시지 구조처럼 보이는

로부터 :

{:from "userid1" :to "userid2" :message "message content"} 

가 서버에 대해 원자의 모든 채널을 찾아 사용자 ID 및 각각의 사용자에 대한 접속 채널로 메시지를 보내고 또한이 접속 레디 스 서버를 통해 메시지를 발행 노드는 채널을 찾는다. ls는 자신의 아톰에 저장되고 각 사용자에게 메시지를 전달합니다.

그래서 내가 겪고있는 문제는 존재감을 적절하게 구현하는 방법입니다. 기본적으로 http-kit는 서버 연결을 처리 할 수 ​​있지만 (클라이언트가 자동으로 다시 연결됨) 채널이 연결을 끊으면 상태가 "서버 닫기"또는 "클라이언트 닫기"상태가되지만 연결이 끊어지면 문제가 발생합니다. 예를 들어 클라이언트 측에서 발생합니다. 사용자가 다른 페이지로 이동하여 몇 초 후에 연결됩니다. 클라이언트 연결이 끊어졌을 때 사용자가 오프라인 상태가 된 것으로 어떻게 결정합니까? 또한 긴 폴링 모드 (긴 폴링 시간 초과는 30 초)에서 메시지 도착 B/W가 다시 연결되는 것에 대해 우려하고 있습니다.

또한 위의 아키텍처에 대한 좋은 존재 메커니즘을 제안하십시오. 감사.

자세한 정보가 필요하면 의견을주십시오. 감사합니다

편집 # 1 :

당신이 채팅 서버에 존재를 구현하는 방법에 대한 좋은 튜토리얼/자료를 추천 해 줄 수 있어요, 난 아무것도 찾을 수가 기운 다.

내 현재 솔루션 -> 특정 사용자 ID의 연결된 채널에 대해 현재 전역 카운트와 마지막으로 연결된 시간 소인을 유지하고 있으며 사용자가 카운트를 끊었을 때 10 초 동안 시간 초과가 구현됩니다. 사용자가 다시 연결 한 경우 (즉, 마지막으로 연결된 스탬프의 길이가 10 초이고 카운트가 여전히 0 임), 그렇지 않은 경우 사용자가 오프라인 상태라고 말하면이 솔루션을 권하고 싶습니다. 방법을 높이 평가합니다. 또한 http-kit에서 timer/scheduled-task를 사용하고 있습니다. 이러한 시간 제한이 중요한 성능 영향을 미칩니 까?

+0

성능이나 모범 사례에 대해 언급 할 수는 없지만 방금 전에 설명한 것처럼 구현했습니다. 그러나 방금 공지 사항을 읽었습니다. https://groups.google.com/forum/#!topic/clojure/5J4L8pbGwGU 추측 컨대 유용 할 수 있습니다. 어쩌면 long-polling과 websocket 연결을위한 일반적인 "client-disconnected"방법이있을 수 있습니다. – sveri

답변

3

여기서 클라이언트 측과는 다른 두 가지 경우가 있습니다.

  1. 롱 폴링. 나는 이것이 어떻게 문제인지를 볼 수 없다. 클라이언트 윈도우가 닫히면, 더 이상 폴링이 없을 것이다. 데이터를 요구하는 고객이 적습니다.
  2. 웹 소켓. 프로토콜에서 사용할 수있는 가까운 방법이 있습니다. 올바르게 구현하면 클라이언트에서 알림을 보내야합니다. 예를 들어 Closing WebSocket correctly (HTML5, Javascript)을 참조하십시오.

는 귀하의 질문에 대답합니까?

+0

답장을 보내 주셔서 감사합니다. 대답은 단순화 된 것입니다. 후속 질문에 대해서는 편집 된 질문을 참조하십시오. 고맙습니다. –