2011-05-08 5 views
1

JavaでのWebサービスは、プログラムがpefectly動作しますが、クライアントがCPUを大量に消費して、アイデアがある:ポーリングが、私はJavaを使用して、チャットサービスやデスクトップクライアントを実装している

  • すべてのクライアントは、イベントキューを持っていますサーバー内で
  • プログラム中に異なるイベントがキューに追加されます。たとえば、新しいユーザーがログインすると、ユーザーリストを更新するためにイベントが追加され、新しいメッセージが送信された場合は別のイベントが追加されます...
  • クライアントには、キュー内のイベントが継続的にポーリングされ、これらのイベントに適切に応答するスレッドがあります。

唯一の問題は、ポーリング・スレッドが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

キューが空のときにポーリングをブロックしませんか? –

+0

ポーリングスレッドのコードを表示することはできますか? –

+0

そのブロックキュー。いくつかのコードスニペットを投稿します。 – AhmadAssaf

答えて

2

代わりにクライアントのポーリングにメインサーバを有するので、私がもしあれば、サーバが適切なクライアントに変更をプッシュしますので、プッシュ技術を使用して言うのを助ける感謝しています。ただし、これは現在のアーキテクチャに応じて多くの変更が必要になることがあります。

UPDATE:

基本的な考え方は次のとおりです。 代わりに、いずれかが存在する場合、サーバーが更新を取得するには、クライアントのポーリングを有していると、彼らは(サーバーから別のスレッドに更新を受け取るのを待っているように、クライアントコードを変更しますクライアント側はサーバーから更新を受け取るのを待っています)。サーバーは、クライアント情報を含むイベントのリストを持つので、正しいデータを正しいクライアントに送信します。

クライアント側では、サーバーに更新を送信するスレッドと、サーバーから更新を受け取るのを待つスレッド(サーバーによってプッシュされる)が少なくとも2つ必要です。

+0

私は建築やデザインを変更する気にしません。学習の目的でこれをやっています...しかし、イベントが彼にプッシュされると、クライアントはどのように知ることができますか?あなたに助けてくれてありがとうございます – AhmadAssaf

+0

WebSocketsのようなものを見てください。ここでJavaの技術のJavaの実装です:http://jwebsocket.org/プッシュ技術(http://jwebsocket.org/demos/chat/chat.htm)を使用してチャットの例を見つけることができます –

+0

@AhmadAssafを参照してください上記の私の更新とLucianoのリンクは、あなたが何かウェブベースのものを作成しているなら、あなたが例として行くのを助けるかもしれません。 – fmucar

関連する問題