protected synchronized void deliverInternal(ChannelImpl channel, Message[] msgs) { if (isLocal()) { // local clients must have a listener ArrayList<Message> list = new ArrayList<Message>(); for (int i = 0; msgs != null && i < msgs.length; i++) { // dont deliver to ourselves if (this != msgs[i].getClient()) list.add(msgs[i]); } if (getListener() != null && list.size() > 0) { getListener().deliver(list.toArray(new Message[0])); } } else { for (int i = 0; msgs != null && i < msgs.length; i++) { MessageImpl message = (MessageImpl) msgs[i]; if (this == message.getClient()) { // dont deliver to ourself continue; } // we are not implementing forever responses, if the client is connected // then we will fire off the message // first we check to see if we have any existing connections we can piggy back on CometEvent event = events.poll(); boolean delivered = false; // TODO TODO - check on thread safety, for writing and for getting last request. if (event != null) { synchronized (event) { RequestBase rq = (RequestBase) event.getHttpServletRequest().getAttribute(RequestBase.LAST_REQ_ATTR); if (rq != null) { Map map = new HashMap(); try { map.put(Bayeux.CHANNEL_FIELD, message.getChannel().getId()); map.put(Bayeux.DATA_FIELD, message); JSONObject json = new JSONObject(map); if (log.isDebugEnabled()) { log.debug( "Message instantly delivered to remote client[" + this + "] message:" + json); } rq.addToDeliveryQueue(this, json); // deliver the batch if (i == (msgs.length - 1)) { rq.deliver(event, this); event.close(); // todo, figure out a better way, this means only one message gets // delivered removeCometEvent(event); // and delivered instantly } delivered = true; } catch (Exception x) { log.error(x); } } } } if (!delivered) { if (log.isDebugEnabled()) { log.debug("Message added to queue for remote client[" + this + "] message:" + message); } // queue the message for the next round messages.add(message); } } } }