用Java轮询Web服务

时间:2011-05-08 14:28:36

标签: java multithreading web-services polling

我已经使用Java实现了聊天服务和桌面客户端,该程序运行良好,但客户端消耗大量CPU,其想法是:

  • 每个客户端在服务器中都有一个事件队列
  • 在程序期间将不同的事件添加到队列中,例如,新用户登录以便添加事件以刷新用户列表,如果发送新消息则添加另一个事件...等等。
  • 客户端有一个线程,它不断轮询其队列中的事件并适当地响应这些事件

唯一的问题是轮询线程占用了大量的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);
    }
}

和队列检查

欣赏帮助

1 个答案:

答案 0 :(得分:2)

我不是让客户端轮询主服务器,而是使用推送技术,因此服务器会将更改推送到适当的客户端(如果有的话)。但是,根据您当前的架构,这可能需要进行大量更改。

更新:

基本思路是: 如果有客户端轮询服务器以获取更新,请更改客户端代码,以便他们等待从服务器接收更新(客户端中的另一个线程等待从服务器接收更新),而不是让客户端轮询服务器以获取更新。服务器将包含一个包含客户端信息的事件列表,因此它会将正确的数据发送给正确的客户端。

因此,在客户端,您将需要至少2个线程用于向服务器发送更新,而另一个用于等待从服务器接收更新(由服务器推送)。