2011-02-01 5 views
4

상태 저장 다중 클라이언트 서버 응용 프로그램을 구현하고 네트워킹/스레드 설계에 대한 몇 가지 질문이 있습니다. 현재 직면하고있는 문제는 통신 레이어와 로직 레이어간에 메시지를 교환하는 방법입니다.Java 다중 스레드 상태 저장 서버 - 네트워킹 디자인

서버는 여러 클라이언트를 처리하며, 각 클라이언트는 여러 개의 "채널"에서 활성화 될 수 있습니다. 각 채널은 여러 단계로 구성되어 있으며 여러 클라이언트가 작동 할 수 있습니다. 여러 방이있는 채팅 프로그램과 비슷한 것으로 생각하십시오.

나는 이미 서버 측에서 메시지 수신을 구현했습니다. 각 클라이언트는 자신의 스레드를 보유하고있어 데이터를 막히고 메시지로 디코딩합니다. 지금 진행하는 방법? 저의 의견으로는, 각 채널은 자신의 상태를 쉽게 유지할 수있는이 스레드를 가져야합니다. BlockingQueue를 사용하여 수신 된 메시지를 채널 스레드와 교환 할 수 있습니다. 채널 스레드는 차단 대기열에서 새 메시지를 기다리고 있습니다.

하지만 클라이언트에게 메시지를 보내려면 어떻게해야합니까? 채널의 논리는 메시지를 처리하고 일부/일부/모든 클라이언트로 전송할 메시지를 생성합니다. 채널 스레드를 사용하여 소켓에 직접 쓰는 것이 안전합니까? 또는 다른 BlockingQueue를 사용하여 메시지를 클라이언트 처리기 스레드로 전송해야합니까? 하지만 소켓을 읽을 때까지 기다리고 있기 때문에 깨우는 방법은 무엇입니까? 아니면 클라이언트마다 별도의 송신 쓰레드를 사용해야합니까, 아니면 별도의 송신 소켓을 사용해야합니까?

BTW : 네트워크 계층에 기존 라이브러리를 사용할 수는 있지만 일반 소켓에서는 처음부터 수행하고 싶습니다.

+0

처리가 싸고 메시지 당이라면 멀티 스레딩을 사용할 수 있을지 잘 모르겠다. 나는 원자로를 대신 사용하는 것을 고려할 것이다. 각 클라이언트 및/또는 채널에 상태가 있다는 사실은 스레드를 사용해야한다는 것을 의미하지는 않습니다. – sinelaw

+0

@sinelaw 귀하가 NIO를 언급 한 것으로 간주합니다. 이 기사에서는 http://paultyma.blogspot.com/2008/03/writing-java-multithreaded-servers.html NIO/IO를 비교하므로 연결 당 하나의 스레드를 사용하기로 결정했습니다 (이미 구현되어 있습니다).). 하지만 채널에 대해 다른 접근 방법을 선택할 수 있습니다 ... 실제 질문은 동일합니다 –

답변

1

소켓을 감싸는 통신 개체에 메시지 보내기 메서드를 넣습니다. 한 번에 하나의 스레드 만 호출 할 수 있도록이 메서드를 동기화하십시오. 그런 다음, 얼마나 많은 스레드가이 메소드를 호출하는지에 차이가 없습니다. 각 메시지는 한 번에 하나씩 만 전송됩니다. 당신은 또한 읽을 블로킹 쓰레드를 방해 할 필요가 없습니다. 이 send 메소드는 스레드가 보내는 동안 다른 스레드가 블로킹하는 것에 대해 걱정할 필요가없는 충분히 빠른 작업입니다.

채널이 연결된 각 클라이언트에 대한 통신 개체에 대한 참조를 가지고 있으면 메시지를 보낼 수 있으며 걱정할 필요가 없습니다.

문제가 발생하는 경우 전송할 메시지를 수정하여 전송할 개체를 대기열에 추가 할 수 있습니다. 그런 다음 큐에서 차단하고 내용을 소켓에 쓸 특정 보내기 스레드를 가질 수 있습니다. 그러나 제 경험으로 볼 때, 이것은 필요하지 않습니다.

+0

그게 내가 "소켓에 직접 쓰는"의미, 나쁜 forumlation했다. 하지만 "메시지를 읽는 중"과 "메시지를 처리하고 여러 클라이언트에 응답을 작성"을 위해 하나의 스레드를 갖는 것이 이상하게 보입니다. 하지만 아마도 이것은 스레드 - 작업 디커플링을위한 나의 취향 일 것입니다 ... –

+0

채널 스레드가 메시지를 처리하고 다중 통신 객체에 응답을 작성하지 않습니까?나는 왜 당신이 그 스레드와 당신의 통신 객체 사이에 어떤 것이 필요할 지 이해하지 못합니다. 효과적으로, 그 쓰레드는 통신 객체를 통해 직접 모든 소켓에 쓰고 있습니다. –

-1

이벤트 메커니즘은 어떻습니까? 요청을 처리 할 준비가되었고 클라이언트 용 데이터가 있으면 클라이언트 소켓 처리기 스레드에 대한 이벤트와 함께 보내십시오. 클라이언트로부터의 전송이 끝났기 때문에 정상적으로 응답을 보낼 수 있습니다.

관련 문제