2015-12-02 117 views
0

我當前深化發展基於這個例子中一個簡單的聊天多房間:大氣框架:廣播廣播消息多次

https://github.com/Atmosphere/atmosphere-samples/blob/master/samples/chat-multiroom/

我的開發環境:

  • Tomee加1.7。 2服務器
  • 大氣運行版本2.4.0
  • Atmosphere-cdi版本2.4.0
  • 的Java EE 1.7
  • 長輪詢協議使用

在解釋我的問題,在這裏聊天室的全球機制,我已經實現:

  1. 用戶A連接到插座「聊天/所有」。這個套接字允許 發送你接收他和他的對話者之間的任何通知。

  2. 用戶A使從所述第一網絡應用聊天請求和等待 (彈出微調)從用戶B的響應

  3. 用戶B也被連接到插座「聊天/所有」 。如果有新的聊天請求 (來自數據庫的SQL請求),則用戶B每次從第二個Web應用程序檢查 。如果他發現了新的請求,他可以或者不接受這個請求。

  4. 用戶B接受來自用戶A的聊天請求。此時,通過 套接字「聊天/全部」,用戶B推送消息表示他接受了這個 請求。之後,用戶B連接到第二個插座 「聊天/ 1」(特定聊天室的隨機ID)。他現在正在等待 (用戶B的彈出式微調),以便用戶A連接到相同的 插槽。

  5. 用戶A收到此消息並連接到套接字「聊天/ 1」。 從服務器,用戶A現在連接到這個聊天室。 這個聊天室中有兩個用戶,我只向用戶B發送消息給 ,通知用戶A已連接並關閉彈出窗口 微調器。

我沒有問題,我只是一個資源廣播消息。但是當我爲兩個用戶廣播消息時,「onMessage」方法被多次調用!

這裏是我的有關管理聊天室代碼:

@ManagedService(path = "/chat/{id_room}") 
public final class ChatRoom { 

//many static final private attribute 

private static final Logger logger = LoggerFactory.getLogger(Chat.class); 

@PathParam("id_room") 
private String idChatRoom; 

private final static String CHAT = "/chat/"; 

private final HashMap<Integer, List<String>> users = new HashMap<Integer, List<String>>(); 

private Universe universe; 

private BroadcasterFactory broadcasterFactory = Universe.broadcasterFactory(); 

private AtmosphereResourceFactory resourceFactory = Universe.resourceFactory();  

private ChatMessageEncoderDecoder chatEncodeDecode = new ChatMessageEncoderDecoder(); 

@Message(encoders = { ChatMessageEncoderDecoder.class }, decoders = { ChatMessageEncoderDecoder.class }) 
public final void onMessage(AtmosphereResource r, final ChatMessage message) throws UnsupportedEncodingException { 
    Integer chatRoomId = !NOTIFICATION_SOCKET_ALL.equals(idChatRoom) == true ? Integer.parseInt(idChatRoom) : 0; 
    [...] 
    if(...) { 
     [...] 
    } 
    else { 
     roomsList.add(idChatRoom); 
     boolean messageEmpty = "".equals(message.getMessage()); 
     boolean chatConnectedWithTwoUsers = users.get(chatRoomId).size() > 1; 
     boolean chatConnectedWithOneUser = users.get(chatRoomId).size() == 1; 
      if(chatConnectedWithTwoUsers && MESSAGE_EVENT.equals(message.getEvent())) { //communication between two users to the chat room id 
       Users user = CDIUtil.getBean(RechercheUserService.class).getUserChat(message.getMail()); 
       if(user != null){ 
        try { 
         List<String> listUsersFromRoom = users.get(chatRoomId); 
         message.setUsers(listUsersFromRoom); 
         message.setEvent(MESSAGE_EVENT); 
         logger.info("{} a envoyé le message {}", message.getAuthor(), message.getMessage()); 

         String messageToSend = chatEncodeDecode.encode(message); 
         broadcasterFactory.lookup(CHAT + idChatRoom).broadcast(messageToSend); 

         String messageUtf8 = new String(message.getMessage().getBytes(), "UTF-8"); 
         CDIUtil.getBean(MessageRoomsService.class).createMessageContents(idChatRoom, user, messageUtf8); 
        } catch (IMException e) { 
         message.setEvent(MESSAGE_NOT_REGISTER_EVENT); 
         logger.error("Impossible d'enregistrer le message de l'utilisateur"); 
        } 
       } 
       else{ 
        message.setEvent(USER_NOT_EXIST_EVENT); 
        logger.error("Utilisateur Inconnu"); 
       } 
      } 
      else if(chatConnectedWithOneUser) { //two users connected to the chat room id 
       users.get(chatRoomId).add(r.uuid()); 
       logger.info("L'utilisateur {} a rejoint le chat {}", r.uuid(), idChatRoom); 

       AtmosphereResource resource = resourceFactory.find(users.get(chatRoomId).get(0)); //get the first user connected to the chat room 

       List<String> listUsersFromRoom = users.get(chatRoomId); 
       message.setUsers(listUsersFromRoom); 
       message.setEvent(CHAT_COMPLETE_EVENT); 

       String messageToSend = chatEncodeDecode.encode(message); 
       broadcasterFactory.lookup(CHAT + idChatRoom).broadcast(messageToSend, resource); 
      } 
     } 
    } 
} 

所以,當播放完成後,在界面的用戶中,有3個消息顯示。例如,用戶A發送消息「你好,我能爲你做什麼?」,用戶B看到這條消息的3倍。

我認爲有三條消息,因爲三個資源在兩個套接字上處於活動狀態。實際上,第一插座「聊天/所有」總是被激活用於一個資源(用戶B)和第二插座「聊天/ 1」爲兩個資源(用戶A和用戶B)活性。有三種資源。

是否有任何人誰已經面臨這個問題呢?或者有沒有人有關於如何解決它的想法?

回答

0

我too..I已經解決了閱讀此鏈接Multiple messages arrive as single response body or message received are incomplete同樣的問題:

我已經加入到web.xml我大氣的Servlet

<init-param> 
    <param-name>org.atmosphere.cpr.AtmosphereInterceptor</param-name> 
    <param-value>org.atmosphere.client.TrackMessageSizeInterceptor</param-value> 
</init-param> 

和客戶端這裏面的init-PARAM我已經加入請求內trackMessageLength : true

var request = { url: document.location.toString() + 'chat', 
       contentType : "application/json", 
       logLevel : 'debug', 
       transport : 'long-polling' , 
       trackMessageLength : true, 
       fallbackTransport: 'long-polling'}; 

從這裏的鏈接報道

如果廣播多封郵件和底層的服務器在內存中緩存它們,你的atmopshere.js回調或功能可與多條消息,而不是一個單一的消息被調用。它可能不是一個問題,如果你使用的文字,但如果你是使用JSON,因爲你的回調/函數獲取與多個JSON消息援引解析可能會失敗。

我希望這也將努力爲您服務!