polling a web service in Java
I have implemented a chat service and desktop client using Java, the program works pefectly but the client is consuming lots of CPU, the idea is :
- Every client has an events queue in the server
- different events are added to the queue during the program, for example a new user logs in so an event is added to refresh the users list, if a new message is sent another event is added ... etc
- the client has a thread that is polling continually for events in its queue and responding to these events appropriately
The only problem is that the polling thread is consuming lots of CPU, i do not know if using Asynchronous web services will help ..
for example :
This is the class where the events are added to the queue
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;
}
}
And this is the polling thread
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开发者_StackOverflow社区 : " + 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);
}
}
And Queue checking
appreciate help
Instead of having the clients polling the main server, I would say use a push technology so the server will push changes to the appropriate client if any. However, this may require a lot of changes depending on your current architecture.
UPDATE:
The basic idea is: Instead of having client poll the server to get updates if there is any, change your client code so that they are waiting to receive updates from server (another thread in the client side waiting to receive updates from server). The server will have a list of events with client information so it will send the correct data to correct client.
So at the client side, you will need at least 2 threads one for sending updates to the server and another that waits to receive updates from server (pushed by server).
精彩评论