2011-05-08 94 views
1

我已經實現了使用Java聊天服務和桌面客戶端,程序工作pefectly但客戶正在消耗大量的CPU,這個想法是:輪詢的Java Web服務

  • 每個客戶端有一個事件隊列在服務器中
  • 在程序期間將不同的事件添加到隊列中,例如新用戶登錄,以便添加事件以刷新用戶列表,如果發送新消息則添加另一事件...等
  • 客戶端有一個線程持續輪詢隊列中的事件並對這些事件做出適當的響應

唯一的問題是,輪詢線程正在消耗大量的CPU,我不知道,如果使用異步Web服務將幫助..

例如:

這是類的地方事件被添加到隊列

public class Session { 

    private String owner; 
    private int sessionID; 
    private BlockingQueue<Events> eventsQueue = new LinkedBlockingQueue<Events>(); 

    public Session() { 
    } 

    public Session(String owner, int sessionID) { 
     this.owner = owner; 
     this.sessionID = sessionID; 
    } 

    public Events getEvent() { 
     try { 
      return eventsQueue.take(); 
     } catch (InterruptedException ex) { 
      System.err.println("Error retreiving Events"); 
     } 
     return null; 
    } 


    public void addEvent(Events ev) { 
     try { 
      eventsQueue.put(ev); 
      eventsQueue.put(ev); 
      System.out.println("New Event Created with ID : " + ev.getId()); 
      System.out.println("Number Of Evenets in Queue " + getOwner() + " : " + eventsQueue.size()); 
     } catch (InterruptedException ex) { 
      System.err.println("Error Creating New Event"); 
     } 
    } 

    public int queueSize() { 
     return eventsQueue.size(); 
    } 

    public String getOwner() { 
     return owner; 
    } 

    public void setOwner(String owner) { 
     this.owner = owner; 
    } 

    public int getSessionID() { 
     return sessionID; 
    } 

    public void setSessionID(int sessionID) { 
     this.sessionID = sessionID; 
    } 
} 

這是輪詢線程

public class pollingThread implements Runnable { 

    public void run() { 
     while (true) { 
      if (checkQueue(Login.getUserName()) != null) { 
       final Events ev = (Events) ObjectSerialization.Deserialize(checkQueue(Login.getUserName())); 
       if (ev != null) { 
        switch (ev.getId()) { 
         case 1: 
          System.out.println("Event Retreived : " + ev.getEventType()); 
          RefreshOnlineList RfEv = (RefreshOnlineList) ev; 
          if (RfEv.getLogEvent().equals("1") && !RfEv.getUname().equals(Login.getUserName())) { 
           Chatter.showTrayMessage(RfEv.getUname() + " Has Just logged In", MessageType.INFO); 
          } else if (!RfEv.getUname().equals(Login.getUserName())) { 
           Chatter.showTrayMessage(RfEv.getUname() + " Has Just logged Out", MessageType.INFO); 
          } 
          Chatter.updateUsersCounter(); 
          Chatter.updateList(); 
          break; 
         case 2: 
          System.out.println("Event Retreived : " + ev.getEventType()); 
          final RegistrationEvent RegEv = (RegistrationEvent) ev; 
          Chatter.showTrayMessage(RegEv.getUser().getUser_name() + " Has Just Registered", MessageType.INFO); 
          SwingUtilities.invokeLater(new Runnable() { 

           public void run() { 
            Chatter.addNewUserPanel(RegEv.getUser()); 
           } 
          }); 
          break; 
         case 3: 
          System.out.println("Event Retreived : " + ev.getEventType()); 
          final ChatRequestEvent ChEv = (ChatRequestEvent) ev; 
          SwingUtilities.invokeLater(
            new Runnable() { 

             public void run() { 
              int res = JOptionPane.showConfirmDialog(
                null, 
                ChEv.getRequestingUser() + " Wishes to connect with you !! ", 
                "Incoming Request", 
                JOptionPane.YES_NO_OPTION); 
              if (res == 1) { 
               replyRequest(ChEv.getRequestingUser(), ChEv.getReceivingUser(), false, ChEv.getRequestID()); 
              } else { 
               chatWindow s = new chatWindow(ChEv.getRequestID(), ChEv.getRequestingUser() + " - " + ChEv.getReceivingUser()); 
               Chatter.addChatwindow(ChEv.getRequestID(), s); 
               Chatter.setUserIsChatting(ChEv.getRequestingUser(), true); 
               chatWindow.main(ChEv.getRequestID(), ChEv.getRequestingUser() + " - " + ChEv.getReceivingUser() + " Are Talking ...", s); 
               replyRequest(ChEv.getRequestingUser(), ChEv.getReceivingUser(), true, ChEv.getRequestID()); 
               startChatSession(Login.getUserName(), ChEv.getRequestingUser(), ChEv.getRequestID(), Chatter.getDate()); 
              } 
             } 
            }); 
          break; 
         case 4: 
          System.out.println("Event Retreived : " + ev.getEventType()); 
          final RequestResponseEvent ResponseEv = (RequestResponseEvent) ev; 
          SwingUtilities.invokeLater(
            new Runnable() { 

             public void run() { 
              if (ResponseEv.isResponse()) { 
               chatWindow s = new chatWindow(ResponseEv.getChatRequestID(), ResponseEv.getRequestinguser() + " - " + ResponseEv.getReceivingUser()); 
               Chatter.addChatwindow(ResponseEv.getChatRequestID(), s); 
               Chatter.setUserIsChatting(ResponseEv.getReceivingUser(), true); 
               chatWindow.main(ResponseEv.getChatRequestID(), ResponseEv.getRequestinguser() + " - " + ResponseEv.getReceivingUser() + " Are Talking ...", s); 
              } else { 
               JOptionPane.showMessageDialog(null, ResponseEv.getReceivingUser() + " Ignored Your Request"); 
              } 
             } 
            }); 
          break; 
         case 5: 
          System.out.println("Event Retreived : " + ev.getEventType()); 
          //Add Code to beautify the message not only the body 
          final SendMessageEvent MessageEv = (SendMessageEvent) ev; 
          SwingUtilities.invokeLater(
            new Runnable() { 

             public void run() { 
              Chatter.addMessage(MessageEv.getMessage(), MessageEv.getChatID()); 
             } 
            }); 
          break; 
         case 6: 
          System.out.println("Event Retreived : " + ev.getEventType()); 
          final LeaveChatEvent LeaveEv = (LeaveChatEvent) ev; 
          SwingUtilities.invokeLater(new Runnable() { 

           public void run() { 
            System.out.println(LeaveEv.getUserName() + " has left the Chat with ID: " + LeaveEv.getChatID()); 
            Chatter.addMessage(new shared.Message(LeaveEv.getUserName(), 1), LeaveEv.getChatID()); 
            Chatter.setUserIsChatting(LeaveEv.getUserName(), false); 
           } 
          }); 
          break; 
         case 7: 
          System.out.println("Event Retreived : " + ev.getEventType()); 
          final GroupChatRequestEvent GroupChatEvent = (GroupChatRequestEvent) ev; 
          SwingUtilities.invokeLater(
            new Runnable() { 

             public void run() { 
              int res = JOptionPane.showConfirmDialog(
                null, 
                GroupChatEvent.getRequestingUser() + " Wants to Join his Group Conference !! ", 
                "Incoming Request", 
                JOptionPane.YES_NO_OPTION); 
              if (res != 1) { 
               chatWindow s = new chatWindow(GroupChatEvent.getChatID(), "Conference - " + GroupChatEvent.getRequestingUser() + " - " + Login.getUserName()); 
               Chatter.addChatwindow(GroupChatEvent.getChatID(), s); 
               Chatter.setUserIsChatting(GroupChatEvent.getRequestingUser(), true); 
               chatWindow.main(GroupChatEvent.getChatID(), "Conference - " + GroupChatEvent.getRequestingUser() + " - " + Login.getUserName() + " Are Talking ...", s); 
               joinChat(Login.getUserName(), GroupChatEvent.getChatID()); 
              } 
             } 
            }); 
          break; 
         case 8: 
          System.out.println("Event Retreived : " + ev.getEventType()); 
          final LeaveChatEvent joinEv = (LeaveChatEvent) ev; 
          SwingUtilities.invokeLater(new Runnable() { 

           public void run() { 
            System.out.println(joinEv.getUserName() + " has Joined the Chat with ID: " + joinEv.getChatID()); 
            Chatter.addMessage(new shared.Message(joinEv.getUserName(), 2), joinEv.getChatID()); 
            Chatter.setUserIsChatting(joinEv.getUserName(), true); 
           } 
          }); 
          break; 
         case 9: 
          System.out.println("Event Retreived : " + ev.getEventType()); 
          final UpdateStatusEvent updateEv = (UpdateStatusEvent) ev; 
          SwingUtilities.invokeLater(new Runnable() { 

           public void run() { 
            System.out.println(updateEv.getUser() + " has updated his status to " + updateEv.getStatus()); 
            Chatter.updateStatusList(updateEv.getUser(), updateEv.getStatus()); 
           } 
          }); 
          break; 
         case 10: 
          System.out.println("Event Retreived : " + ev.getEventType()); 
          final RefreshDetailsEvent refEvenet = (RefreshDetailsEvent) ev; 
          SwingUtilities.invokeLater(new Runnable() { 

           public void run() { 
            System.out.println(refEvenet.getUser() + " has updated his Details "); 
            Chatter.updateDetails(refEvenet.getUser()); 
           } 
          }); 
          break; 
         case 11: 
          System.out.println("Event Retreived : " + ev.getEventType()); 
          final BlockedEvent BlockedEv = (BlockedEvent) ev; 
          SwingUtilities.invokeLater(new Runnable() { 

           public void run() { 
            System.out.println(BlockedEv.getUserName() + " has Been Blocked "); 
            JOptionPane.showMessageDialog(null, "You have Been Blocked\nReason: " + BlockedEv.getReason()); 
            Chatter.signOut(); 
           } 
          }); 
          break; 
        } 
       } 
      } 
     } 
    } 

    private static byte[] checkQueue(java.lang.String uname) { 
     db.Database service = new db.Database(); 
     db.DatabasePortType port = service.getDatabaseHttpSoap12Endpoint(); 
     return port.checkQueue(uname); 
    } 

    private static void replyRequest(java.lang.String requestingUser, java.lang.String receivingUser, java.lang.Boolean result, java.lang.Integer id) { 
     db.Database service = new db.Database(); 
     db.DatabasePortType port = service.getDatabaseHttpSoap12Endpoint(); 
     port.replyRequest(requestingUser, receivingUser, result, id); 
    } 

    private static void startChatSession(java.lang.String initiatingUser, java.lang.String receivingUser, java.lang.Integer id, java.lang.String sessionTime) { 
     db.Database service = new db.Database(); 
     db.DatabasePortType port = service.getDatabaseHttpSoap12Endpoint(); 
     port.startChatSession(initiatingUser, receivingUser, id, sessionTime); 
    } 

    private static void joinChat(java.lang.String uname, java.lang.Integer chatID) { 
     db.Database service = new db.Database(); 
     db.DatabasePortType port = service.getDatabaseHttpSoap12Endpoint(); 
     port.joinChat(uname, chatID); 
    } 
} 

和隊列檢查

欣賞幫助

+0

當隊列爲空時輪詢是否阻塞? – 2011-05-08 14:35:37

+0

也許你可以顯示輪詢線程的代碼? – 2011-05-08 14:35:56

+0

其阻塞隊列..病後發佈一些代碼片段 – AhmadAssaf 2011-05-08 14:40:02

回答

2

而不是由客戶投票的主服務器的,我會說使用推送技術,因此如果所有服務器將更改推送到相應的客戶端。但是,這可能需要根據您當前的體系結構進行很多更改。

UPDATE:

的基本思路是: 而不必客戶端輪詢服務器以獲取更新,如果有任何,改變你的客戶端代碼,以便他們在等待接收來自服務器的更新(在另一個線程客戶端等待從服務器接收更新)。服務器將擁有包含客戶端信息的事件列表,以便將正確的數據發送給正確的客戶端。

所以在客戶端,至少需要2個線程用於向服務器發送更新,另一個線程等待從服務器接收更新(由服務器推送)。

+0

我不介意更改架構或設計..我是這樣做的學習目的..但如何能讓客戶知道什麼時候推送給他一個事件.. ID感謝您的幫助 – AhmadAssaf 2011-05-08 14:50:52

+0

看看像WebSockets的東西。以下是Java中Java技術的實現:http://jwebsocket.org/您可以使用推送技術找到一個聊天示例(http://jwebsocket.org/demos/chat/chat.htm) – 2011-05-08 14:55:57

+0

@AhmadAssaf請參閱我上面的更新和Luciano的鏈接可能會幫助你開始一個例子,如果你正在創建一些基於Web的東西。 – fmucar 2011-05-08 15:00:41