From 90cba45497d0130b5d4836c05383de6ba8119f8f Mon Sep 17 00:00:00 2001 From: "marcins78@gmail.com" Date: Fri, 4 Jan 2013 03:00:40 +0000 Subject: [PATCH] Changing how chat works to make it less prone to errors. --- .../com/gempukku/lotro/chat/ChatRoom.java | 3 +- .../gempukku/lotro/chat/ChatRoomMediator.java | 4 +- .../lotro/chat/UserUnsubscribedException.java | 4 + .../gempukku/lotro/server/ChatResource.java | 20 +- .../src/main/webapp/js/gemp-014/chat.js | 191 +++++++----------- .../main/webapp/js/gemp-014/communication.js | 7 +- 6 files changed, 98 insertions(+), 131 deletions(-) create mode 100644 gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/chat/UserUnsubscribedException.java diff --git a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/chat/ChatRoom.java b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/chat/ChatRoom.java index 1ccf9e516..e557c8664 100644 --- a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/chat/ChatRoom.java +++ b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/chat/ChatRoom.java @@ -23,8 +23,7 @@ public class ChatRoom { shrinkLastMessages(); } for (Map.Entry listeners : _chatRoomListeners.entrySet()) - if (!listeners.getKey().equals(from)) - listeners.getValue().messageReceived(chatMessage); + listeners.getValue().messageReceived(chatMessage); } public void postMessage(String from, String message) { diff --git a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/chat/ChatRoomMediator.java b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/chat/ChatRoomMediator.java index 71097d47e..beecab554 100644 --- a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/chat/ChatRoomMediator.java +++ b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/chat/ChatRoomMediator.java @@ -39,12 +39,12 @@ public class ChatRoomMediator { } } - public List getPendingMessages(String playerId) { + public List getPendingMessages(String playerId) throws UserUnsubscribedException { _lock.readLock().lock(); try { GatheringChatRoomListener gatheringChatRoomListener = _listeners.get(playerId); if (gatheringChatRoomListener == null) - throw new WebApplicationException(Response.Status.NOT_FOUND); + throw new UserUnsubscribedException(); return gatheringChatRoomListener.consumeMessages(); } finally { _lock.readLock().unlock(); diff --git a/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/chat/UserUnsubscribedException.java b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/chat/UserUnsubscribedException.java new file mode 100644 index 000000000..0d4e1e9ca --- /dev/null +++ b/gemp-lotr/gemp-lotr-server/src/main/java/com/gempukku/lotro/chat/UserUnsubscribedException.java @@ -0,0 +1,4 @@ +package com.gempukku.lotro.chat; + +public class UserUnsubscribedException extends Exception { +} diff --git a/gemp-lotr/gemp-lotr-web-server/src/main/java/com/gempukku/lotro/server/ChatResource.java b/gemp-lotr/gemp-lotr-web-server/src/main/java/com/gempukku/lotro/server/ChatResource.java index 0b704d572..faa06e109 100644 --- a/gemp-lotr/gemp-lotr-web-server/src/main/java/com/gempukku/lotro/server/ChatResource.java +++ b/gemp-lotr/gemp-lotr-web-server/src/main/java/com/gempukku/lotro/server/ChatResource.java @@ -3,6 +3,7 @@ package com.gempukku.lotro.server; import com.gempukku.lotro.chat.ChatMessage; import com.gempukku.lotro.chat.ChatRoomMediator; import com.gempukku.lotro.chat.ChatServer; +import com.gempukku.lotro.chat.UserUnsubscribedException; import com.gempukku.lotro.game.Player; import com.sun.jersey.spi.resource.Singleton; import org.apache.commons.lang.StringEscapeUtils; @@ -73,18 +74,23 @@ public class ChatResource extends AbstractResource { } } - List chatMessages = chatRoom.getPendingMessages(resourceOwner.getName()); + try { + List chatMessages = chatRoom.getPendingMessages(resourceOwner.getName()); - Collection usersInRoom = chatRoom.getUsersInRoom(); + Collection usersInRoom = chatRoom.getUsersInRoom(); - DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); - DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); + DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); - Document doc = documentBuilder.newDocument(); + Document doc = documentBuilder.newDocument(); - serializeChatRoomData(room, chatMessages, usersInRoom, doc); + serializeChatRoomData(room, chatMessages, usersInRoom, doc); - return doc; + return doc; + } catch (UserUnsubscribedException exp) { + sendError(Response.Status.GONE); + return null; + } } private void serializeChatRoomData(String room, List chatMessages, Collection usersInRoom, Document doc) { diff --git a/gemp-lotr/gemp-lotr-web/src/main/webapp/js/gemp-014/chat.js b/gemp-lotr/gemp-lotr-web/src/main/webapp/js/gemp-014/chat.js index 4996626b0..01c8af08d 100644 --- a/gemp-lotr/gemp-lotr-web/src/main/webapp/js/gemp-014/chat.js +++ b/gemp-lotr/gemp-lotr-web/src/main/webapp/js/gemp-014/chat.js @@ -2,55 +2,34 @@ var ChatBoxUI = Class.extend({ name:null, div:null, communication:null, + chatMessagesDiv:null, chatTalkDiv:null, chatListDiv:null, + showTimestamps:false, maxMessageCount:500, talkBoxHeight:25, + chatUpdateInterval:1000, - unsentMessages:null, - processingMessages:null, - retryCount:null, - maxRetryCount:5, + playerListener:null, hiddenClasses:null, + hideSystemButton:null, lockButton:null, + lockChat:false, + stopUpdates: false, init:function (name, div, url, showList, playerListener, showHideSystemButton, showLockButton) { var that = this; this.hiddenClasses = new Array(); this.playerListener = playerListener; - this.retryCount = 0; this.name = name; this.div = div; - this.unsentMessages = new Array(); this.communication = new GempLotrCommunication(url, function (xhr, ajaxOptions, thrownError) { - if (thrownError != "abort") { - if (xhr != null) { - that.retryCount++; - if (that.retryCount <= that.maxRetryCount) { - that.appendMessage("Chat had a problem communicating with the server (error " + xhr.status + "). Retrying (" + that.retryCount + " of " + that.maxRetryCount + ")...", "systemMessage"); - setTimeout(function () { - that.updateChatMessages(); - }, that.chatUpdateInterval); - } else { - that.appendMessage("Chat has given up on connection retry (tried " + that.maxRetryCount + "), make sure your connection with the Internet is working.", "warningMessage"); - } - return; - } - that.retryCount++; - if (that.retryCount <= that.maxRetryCount) { - that.appendMessage("Chat had an unkown problem communicating with the server. Retrying (" + that.retryCount + " of " + that.maxRetryCount + ")...", "systemMessage"); - setTimeout(function () { - that.updateChatMessages(); - }, that.chatUpdateInterval); - } else { - that.appendMessage("Chat has given up on connection retry (tried " + that.maxRetryCount + "), make sure your connection with the Internet is working.", "warningMessage"); - } - } + that.appendMessage("Unkown chat problem occured (error=" + xhr.status + ")", "warningMessage"); }); this.chatMessagesDiv = $("
"); @@ -61,37 +40,37 @@ var ChatBoxUI = Class.extend({ if (showHideSystemButton) { this.hideSystemButton = $("").button( - {icons:{ - primary:"ui-icon-zoomin" - }, text:false}); + {icons:{ + primary:"ui-icon-zoomin" + }, text:false}); this.hideSystemButton.click( - function () { - if (that.isShowingMessageClass("systemMessage")) { - $('#showSystemMessages').button("option", "icons", {primary:'ui-icon-zoomin'}); - that.hideMessageClass("systemMessage"); - } else { - $('#showSystemMessages').button("option", "icons", {primary:'ui-icon-zoomout'}); - that.showMessageClass("systemMessage"); - } - }); + function () { + if (that.isShowingMessageClass("systemMessage")) { + $('#showSystemMessages').button("option", "icons", {primary:'ui-icon-zoomin'}); + that.hideMessageClass("systemMessage"); + } else { + $('#showSystemMessages').button("option", "icons", {primary:'ui-icon-zoomout'}); + that.showMessageClass("systemMessage"); + } + }); this.hideMessageClass("systemMessage"); } if (showLockButton) { this.lockButton = $("").button( - {icons:{ - primary:"ui-icon-locked" - }, text:false}); + {icons:{ + primary:"ui-icon-locked" + }, text:false}); this.lockButton.click( - function () { - if (that.lockChat) { - $('#lockChatButton').button("option", "icons", {primary:'ui-icon-locked'}); - that.lockChat = false; - } else { - $('#lockChatButton').button("option", "icons", {primary:'ui-icon-unlocked'}); - that.lockChat = true; - } - }); + function () { + if (that.lockChat) { + $('#lockChatButton').button("option", "icons", {primary:'ui-icon-locked'}); + that.lockChat = false; + } else { + $('#lockChatButton').button("option", "icons", {primary:'ui-icon-unlocked'}); + that.lockChat = true; + } + }); } if (showList) { @@ -105,28 +84,16 @@ var ChatBoxUI = Class.extend({ this.div.append(this.chatTalkDiv); this.communication.startChat(this.name, - function (xml) { - that.processMessages(xml, true); - }, { - "401":function () { - that.appendMessage("You are not logged in, go to the main page to log in.", "warningMessage"); - }, - "403":function () { - that.appendMessage("You have no permission to join this chat.", "warningMessage"); - }, - "404":function () { - that.appendMessage("Chat room was closed, please go to the Game Hall.", "warningMessage"); - } - }); + function (xml) { + that.processMessages(xml, true); + }, this.chatErrorMap()); this.chatTalkDiv.bind("keypress", function (e) { var code = (e.keyCode ? e.keyCode : e.which); if (code == 13) { var value = $(this).val(); - if (value != "") { + if (value != "") that.sendMessage(value); - that.appendMessage("Me: " + that.escapeHtml(value)); - } $(this).val(""); } }); @@ -214,7 +181,6 @@ var ChatBoxUI = Class.extend({ var root = xml.documentElement; if (root.tagName == 'chat') { this.retryCount = 0; - this.processingMessages = null; var messages = root.getElementsByTagName("message"); for (var i = 0; i < messages.length; i++) { var message = messages[i]; @@ -264,59 +230,50 @@ var ChatBoxUI = Class.extend({ } }, - updateChatMessages:function (xml) { + updateChatMessages:function () { var that = this; - if (this.processingMessages != null) { - this.communication.sendChatMessage(this.name, this.processingMessages, function (xml) { - that.processMessages(xml, true); - }, { - "401":function () { - that.appendMessage("You are not logged in, go to the main page to log in.", "warningMessage"); - }, - "403":function () { - that.appendMessage("You have no permission to send messages to this chat.", "warningMessage"); - }, - "404":function () { - that.appendMessage("Chat room was closed, or you were inactive for too long, please go to the Game Hall.", "warningMessage"); - } - }); - } else if (this.unsentMessages.length > 0) { - this.communication.sendChatMessage(this.name, this.unsentMessages, function (xml) { - that.processMessages(xml, true); - }, { - "401":function () { - that.appendMessage("You are not logged in, go to the main page to log in.", "warningMessage"); - }, - "403":function () { - that.appendMessage("You have no permission to send messages to this chat.", "warningMessage"); - }, - "404":function () { - that.appendMessage("Chat room was closed, or you were inactive for too long, please go to the Game Hall.", "warningMessage"); - } - }); - this.processingMessages = this.unsentMessages; - this.unsentMessages = new Array(); - } else { - this.communication.updateChat(this.name, function (xml) { - that.processMessages(xml, true); - }, { - "401":function () { - that.appendMessage("You are not logged in, go to the main page to log in.", "warningMessage"); - }, - "403":function () { - that.appendMessage("You have no permission to get message from this chat.", "warningMessage"); - }, - "404":function () { - that.appendMessage("Chat room was closed, or you were inactive for too long, please go to the Game Hall.", "warningMessage"); - } - }); - } + this.communication.updateChat(this.name, function (xml) { + that.processMessages(xml, true); + }, this.chatErrorMap()); }, sendMessage:function (message) { var that = this; + this.communication.sendChatMessage(this.name, message, function(xml) { + that.processMessages(xml, false); + }, this.chatErrorMap()); + }, - this.unsentMessages.push(message); + chatMalfunction: function() { + this.stopUpdates = true; + this.chatTalkDiv.prop('disabled', true); + this.chatTalkDiv.css({"background-color": "#ff9999"}); + }, + + chatErrorMap:function() { + var that = this; + return { + "0":function() { + that.chatMalfunction(); + that.appendMessage("Chat server has been closed or there was a problem with your internet connection.", "warningMessage"); + }, + "401":function() { + that.chatMalfunction(); + that.appendMessage("You are not logged in.", "warningMessage"); + }, + "403": function() { + that.chatMalfunction(); + that.appendMessage("You have no permission to participate in this chat.", "warningMessage"); + }, + "404": function() { + that.chatMalfunction(); + that.appendMessage("Chat room is closed.", "warningMessage"); + }, + "410": function() { + that.chatMalfunction(); + that.appendMessage("You have been inactive for too long and were removed from the chat room. Refresh the page if you wish to re-enter.", "warningMessage"); + } + }; } }); \ No newline at end of file diff --git a/gemp-lotr/gemp-lotr-web/src/main/webapp/js/gemp-014/communication.js b/gemp-lotr/gemp-lotr-web/src/main/webapp/js/gemp-014/communication.js index f80e205e1..35461d5de 100644 --- a/gemp-lotr/gemp-lotr-web/src/main/webapp/js/gemp-014/communication.js +++ b/gemp-lotr/gemp-lotr-web/src/main/webapp/js/gemp-014/communication.js @@ -456,7 +456,7 @@ var GempLotrCommunication = Class.extend({ cache:false, data:{ participantId:getUrlParam("participantId")}, - success:this.deliveryCheck(callback), + success:callback, error:this.errorCheck(errorMap), dataType:"xml" }); @@ -468,7 +468,7 @@ var GempLotrCommunication = Class.extend({ cache:false, data:{ participantId:getUrlParam("participantId")}, - success:this.deliveryCheck(callback), + success:callback, error:this.errorCheck(errorMap), dataType:"xml" }); @@ -478,10 +478,11 @@ var GempLotrCommunication = Class.extend({ type:"POST", url:this.url + "/chat/" + room, cache:false, + async:false, data:{ participantId:getUrlParam("participantId"), message:messages}, - success:this.deliveryCheck(callback), + success:callback, traditional:true, error:this.errorCheck(errorMap), dataType:"xml"