2011-05-08 95 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