2010-12-28 3 views
4

대기 런타임 0.6 스냅 샷을 사용하고 있습니다. Tomcat 7이 Http11 Nio 커넥터를 사용하고 있고 BlockingIO가 사용될 것이라는 경고가 없다는 것을 올바르게 기록하고 있습니다.대기열 런타임을 사용하는 단일 연결로 브로드 캐스트 할 수 없습니다.

3 가지 종류의 채널에 메시지를 보내려고합니다.

  1. 전역 브로드 캐스터 - 일시 중단 된 모든 리소스로 브로드 캐스팅됩니다. (전체)
  2. 방송 특정 자원 (예를 들어, 파트너)에 현재의 자원에
  3. 방송을 위해 내가 세션에 저장해야하는 일 모두 (자기) 로그인 액션이 발생

, 이런 종류의 방송을 할 수 있을까요? 다음과 같이

내 코드의 일부 세부 사항은 다음과 같습니다

  1. 내 핸들러는 생성자에서 AtmosphereHandler
  2. 를 구현하고, 다음과 같이 나는 globalBroadcaster를 인스턴스화 : 로그인에

    globalBroadcaster = new DefaultBroadcaster();

  3. ,

    resource.getAtmosphereConfig().getServletContext().setAttribute(name, selfBroadcaster); 여기서 name은 요청 매개 변수의 사용자 이름이고 selfBroadcaster는 DefaultBroadcaster의 새 인스턴스입니다. 여기

  4. private synchronized void sendMessageToPartner(Broadcaster selfBroadcaster, AtmosphereResource<HttpServletRequest, HttpServletResponse> resource,String name, String message) {
    // this gives the partner's name
    String partner= (String) resource.getAtmosphereConfig().getServletContext().getAttribute(name + PARTNER_NAME_TOKEN);
    // get partner's broadcaster
    Broadcaster outsiderBroadcaster = (Broadcaster) resource
    .getAtmosphereConfig().getServletContext()
    .getAttribute(partner);
    if (outsiderBroadcaster == null) {
    sendMessage(selfBroadcaster, "Invalid user " + partner);
    return;
    }
    // broadcast to partner
    outsiderBroadcaster.broadcast(" **" + message);

은 내가 필요한 모든 정보를 제공 한 희망 sendMessageToPartner 코드입니다. 필요한 경우 더 많은 정보를 제공 할 수 있습니다.

문제는 글로벌 메시지가 전송된다는 것입니다. 파트너에게 보내는 메시지가 전송 될 때 가끔 차단되고 메시지가 클라이언트에서 전혀 수신되지 않습니다. 이것은 3-4 개의 메시지 이후에 일관되게 발생합니다.

스레딩 문제가 있습니까? 내가 도대체 ​​뭘 잘못하고있는 겁니까?

누군가가 나를 도와 주길 바랍니다.

답변

6

좋아,이 방법을 분위기 런타임에서 어떻게 구현할 수 있는지 알아 냈습니다. 먼저 0.7 스냅 샷으로 업그레이드했지만 동일한 로직이 0.6에서도 작동 할 것으로 생각합니다.

로그인 작업을 호출
// Use one Broadcaster per AtmosphereResource    
try {  
atmoResource.setBroadcaster(BroadcasterFactory.getDefault().get());  

} catch (Throwable t) { 
       throw new IOException(t); 
      } 

      // Create a Broadcaster based on this session id. 
      selfBroadcaster = atmoResource.getBroadcaster(); 
      // add to the selfBroadcaster 
      selfBroadcaster.addAtmosphereResource(atmoResource); 

      atmoResource.suspend(); 

, 마지막으로

//Get this broadcaster from session and add it to BroadcasterFactory. 

Broadcaster selfBroadcaster = (Broadcaster) session.getAttribute(sessionId); 

BroadcasterFactory.getDefault().add(selfBroadcaster, name); 

Now the global broadcaster. The logic here is, you create a broadcaster from the first resource and then add each resource as they log in. 

Broadcaster globalBroadcaster; 

globalBroadcaster = BroadcasterFactory.getDefault().lookup(DefaultBroadcaster.class, GLOBAL_TOKEN, false); 
       if (globalBroadcaster == null) { 
        globalBroadcaster = selfBroadcaster; 

        } else { 
         BroadcasterFactory.getDefault().remove(
           globalBroadcaster, GLOBAL_TOKEN); 
         AtmosphereResource r = (AtmosphereResource) session 
           .getAttribute("atmoResource"); 
         globalBroadcaster.addAtmosphereResource(r); 

        } 
        BroadcasterFactory.getDefault().add(globalBroadcaster, 
          GLOBAL_TOKEN); 

, 당신이 싱글로 방송 할 수있다, GET 요청에

:

그래서, 단일 사용자에 대한 방송을 만들 수 있습니다 연결 또는 다음과 같이 모든 연결에 대해 전역으로 연결하십시오.

// Single Connection/Session 
Broadcaster singleBroadcaster= BroadcasterFactory.getDefault().lookup(
          DefaultBroadcaster.class, name); 
singleBroadcaster.broadcast("Only for you"); 

// Global 
Broadcaster globalBroadcaster = BroadcasterFactory.getDefault().lookup(DefaultBroadcaster.class,GLOBAL_TOKEN, false); 
globalBroadcaster.broadcast("Global message to all"); 

파트너에게 메시지를 보내려면 파트너의 브로드 캐스터를 조회하고 위와 동일하게 단일 연결을 수행하십시오.

희망을 얻으려는 사람에게 도움이되기를 바랍니다. 더 좋은 방법이있을 수 있습니다. 누군가가 더 나은 해결책을 제시하기 전까지는이 접근법을 사용해야한다고 생각합니다.

관련 문제