2012-06-20 3 views
2

그래서 Socket.IO 확장에 대한 몇 가지 기사를 읽었습니다. 여러 가지 이유로 저는 내장 된 Socket.IO 스케일링 메커니즘을 사용하고 싶지 않습니다. (주로 비효율적 인 것처럼 보입니다. 내 관점에서 볼 때 Redis에 더 많은 내용을 게시하기 때문입니다.) Redis 클라이언트 브로드 캐스트 문제 (Socket.IO의 컨텍스트에서)

그래서 나는이 간단한 아이디어를 내놓았다했습니다

각 Socket.IO 서버는 레디 스 펍/서브/저장 클라이언트를 생성 레디 스에 연결하고 채널에 등록합니다. 이제 데이터를 브로드 캐스트하려면 Redis와 다른 모든 Socket.IO 서버에 게시하여 사용자에게 전달하십시오.

그러나 문제가 있습니다 (Socket.IO 내장 메커니즘의 경우에도 문제라고 생각합니다). 연결된 모든 사용자의 수를 알고 싶다고합시다.

  1. 서버 A는 레디 스에 give_me_clients를 게시 : 그 일을 적어도 두 가지 방법이 있습니다. 그런 다음 각 Socket.IO 서버는 연결을 계산하고 number_of_clients을 게시합니다. 서버 A는이 데이터를 수집하여 결합하여 클라이언트로 보냅니다.

  2. 각 서버는 사용자가 서버에 연결/연결 해제 할 때마다 Redis에서 number_of_clients_for::ID_HERE을 업데이트합니다. 그런 다음 서버 A는 데이터를 가져 와서 결합합니다. 더 효율적 일 수 있습니다.

하지만 이러한 솔루션에 문제가 있습니다

  1. 서버 A는 다른 서버의 인식하지 못합니다. 그러므로 그는 언제 그가 number_of_clients을 듣지 말아야할지 모릅니다. 서버 A가 다른 서버를 인식하도록 수정하면 서버가 Redis에 연결될 때마다 new_server (서버 A가 데이터를 가져 와서 메모리에 저장함)을 게시합니다. 하지만 Redis - Socket.IO 연결이 끊어지면 어떻게해야합니까? Redis가 클라이언트 중 하나가 연결 해제되었음을 고객에게 알리는 방법이 있습니까?

  2. 실제로 위와 동일합니다. Socket.IO 서버가 데이터를 지우는 데 number_of_clients 데이터를 지울 때?

그래서 진짜 질문은 : 그들 중 하나와의 연결이 방금 종료 된 것을 클라이언트 (샤넬 게시)에 통지 레디 스 수 있습니까 ??

답변

2

많은 테스트를 거친 후 Redis에는 그러한 기능이 없다고합니다. 또한 Socket을 확장한다는 사실을 알았습니다 .IO는 정말 고통 스럽습니다.

그래서 Socket.IO에서 WS로 전환했습니다 (this link 참조). 저레벨이지만 (내 사용에는 완벽 함) 모든 웹 버전에서 WebSocket 만 지원합니다. 그러나 다시 나는 WebSocket과 FlashSocket (수동으로 구현해야하지만, 괜찮습니다) 만 지원하려고합니다.

이점은 그러한 서버로 클러스터를 쉽게 만들 수 있다는 것입니다. HAProxy는 거의 그대로 상자에서 작동합니다 (약간의 미세 조정). 서버는 로컬 넷 (클러스터가 클 경우 UDP 또는 중앙 TCP 서버와 함께)에서 쉽게 통신 할 수 있습니다.

단점은 하트 비트, 브로드 캐스팅, 회의실 등과 같은 멋진 기능을 수동으로 구현해야한다는 것입니다. 또한 폴링 폴백을 원하지만 내 경우에는 괜찮습니다. 스케일링은 여전히 ​​중요합니다.

+0

나는 ws로 전환했다. 기본적으로 process.on을 종료하고'wss.clients'를 통해 반복하고 내 redis 저장소 (서버가 실패한 경우)의 'user : ids'를 모두 삭제한다. 내가 가지고있는 간단한 문제 중 하나는 비공개 메시지입니다. 포트 9300과 9301에 2 대의 ws 서버가 있고 9301의 사용자가 9300에있는 사용자에게 메시지를 보내려는 경우 (또는 다른 서버/포트 일 수 있음) 다른 사용자가 알고있다. 개인 메시지 요청을 redis 서버에 게시하고 사용자가 메시지를 보내려면 어떤 wss 서버인지 알아 내야합니까? –

+1

@NiCkNewman 각 사용자마다 Redis와 같은 하나의 공유 된 장소에서 해당 사용자가 어떤 서버인지에 대한 정보를 유지해야한다고 생각합니다. 그런 다음 해당 정보를 검색하고 대상 서버에 직접 메시지를 보냅니다. 그러나 가장 효율적인 방법은 사용자가 자신의 친구가있는 서버를 인식하고 해당 서버에 직접 메시지를 보내는 것입니다. – freakish

+0

물론 그 모두는 문맥에 달려 있습니다. 예를 들어 채팅 기록 (예 : Facebook)을 유지하려는 경우 모두 더 복잡해집니다. 채팅 서버에 대한 많은 경험이 없으므로 잘못된 방향으로 인도하고 싶지 않습니다. :( – freakish