Index: lams_learning/src/java/org/lamsfoundation/lams/learning/presence/PresenceWebsocketServer.java =================================================================== diff -u -rc16be665439195a6d3d0abfbcb08014c65a24a93 -rdc5dd92e6e228be6f24684924c3a2adc49a2c091 --- lams_learning/src/java/org/lamsfoundation/lams/learning/presence/PresenceWebsocketServer.java (.../PresenceWebsocketServer.java) (revision c16be665439195a6d3d0abfbcb08014c65a24a93) +++ lams_learning/src/java/org/lamsfoundation/lams/learning/presence/PresenceWebsocketServer.java (.../PresenceWebsocketServer.java) (revision dc5dd92e6e228be6f24684924c3a2adc49a2c091) @@ -124,36 +124,31 @@ lastSendTimes.put(lessonId, System.currentTimeMillis()); } - Set lessonWebsockets = PresenceWebsocketServer.websockets.get(lessonId); + Set lessonWebsockets = new HashSet(PresenceWebsocketServer.websockets.get(lessonId)); Roster roster = PresenceWebsocketServer.rosters.get(lessonId); JSONArray rosterJSON = roster.getRosterJSON(); - // synchronize websockets as a new Learner entering chat could modify this collection - synchronized (lessonWebsockets) { - Iterator websocketIterator = lessonWebsockets.iterator(); - while (websocketIterator.hasNext()) { - Websocket websocket = websocketIterator.next(); - // if this run is meant only for one learner, skip the others - if ((nickName != null) && !nickName.equals(websocket.nickName)) { - continue; - } + // make a copy of the websocket collection so it does not get blocked while sending messages + for (Websocket websocket : lessonWebsockets) { + // if this run is meant only for one learner, skip the others + if ((nickName != null) && !nickName.equals(websocket.nickName)) { + continue; + } - // the connection is valid, carry on - JSONObject responseJSON = new JSONObject(); + // the connection is valid, carry on + JSONObject responseJSON = new JSONObject(); - try { - // if it is just roster, skip messages - if (roster.imEnabled) { - JSONArray messagesJSON = PresenceWebsocketServer.filterMessages(messages, - websocket.nickName); - responseJSON.put("messages", messagesJSON); - } - responseJSON.put("roster", rosterJSON); - - // send the payload to the Learner's browser - websocket.session.getBasicRemote().sendText(responseJSON.toString()); - } catch (Exception e) { - PresenceWebsocketServer.log.error("Error while building message JSON", e); + try { + // if it is just roster, skip messages + if (roster.imEnabled) { + JSONArray messagesJSON = PresenceWebsocketServer.filterMessages(messages, websocket.nickName); + responseJSON.put("messages", messagesJSON); } + responseJSON.put("roster", rosterJSON); + + // send the payload to the Learner's browser + websocket.session.getBasicRemote().sendText(responseJSON.toString()); + } catch (Exception e) { + PresenceWebsocketServer.log.error("Error while building message JSON", e); } } }