diff --git a/src/java/org/jivesoftware/multiplexer/net/http/HttpSession.java b/src/java/org/jivesoftware/multiplexer/net/http/HttpSession.java index 5018542..99e1df0 100644 --- a/src/java/org/jivesoftware/multiplexer/net/http/HttpSession.java +++ b/src/java/org/jivesoftware/multiplexer/net/http/HttpSession.java @@ -35,7 +35,7 @@ private boolean isSecure; private int maxPollingInterval; private long lastPoll = -1; - private Set listeners = new HashSet(); + private Set listeners = new HashSet(); private boolean isClosed; private int inactivityTimeout; @@ -43,7 +43,9 @@ super(serverName, null, streamID); } - void addConnection(HttpConnection connection, boolean isPoll) throws HttpBindException { + void addConnection(HttpConnection connection, boolean isPoll) throws HttpBindException, + HttpConnectionClosedException + { if(connection == null) { throw new IllegalArgumentException("Connection cannot be null."); } @@ -58,18 +60,32 @@ } connection.setSession(this); - if(pendingElements.size() > 0) { - createDeliverable(pendingElements); + if (pendingElements.size() > 0) { + String deliverable = createDeliverable(pendingElements); pendingElements.clear(); - return; + fireConnectionOpened(connection); + connection.deliverBody(deliverable); + fireConnectionClosed(connection); } - // With this connection we need to check if we will have too many connections open, closing - // any extras. - while(hold > 0 && connectionQueue.size() >= hold) { - HttpConnection toClose = connectionQueue.remove(); - toClose.close(); + else { + // With this connection we need to check if we will have too many connections open, + // closing any extras. + while (hold > 0 && connectionQueue.size() >= hold) { + HttpConnection toClose = connectionQueue.remove(); + toClose.close(); + fireConnectionClosed(toClose); + } + connectionQueue.offer(connection); + fireConnectionOpened(connection); } - connectionQueue.offer(connection); + } + + private void fireConnectionOpened(HttpConnection connection) { + Collection listeners = + new HashSet(this.listeners); + for(SessionListener listener : listeners) { + listener.connectionOpened(this, connection); + } } private void checkPollingInterval() throws HttpBindException { @@ -98,10 +114,10 @@ failDelivery(); } - Collection listeners = - new HashSet(this.listeners); + Collection listeners = + new HashSet(this.listeners); this.listeners.clear(); - for(SessionCloseListener listener : listeners) { + for(SessionListener listener : listeners) { listener.sessionClosed(this); } } @@ -127,6 +143,7 @@ try { connection.deliverBody(deliverable); delivered = true; + fireConnectionClosed(connection); } catch (HttpConnectionClosedException e) { /* Connection was closed, try the next one */ @@ -138,6 +155,14 @@ } } + private void fireConnectionClosed(HttpConnection connection) { + Collection listeners = + new HashSet(this.listeners); + for(SessionListener listener : listeners) { + listener.connectionClosed(this, connection); + } + } + private String createDeliverable(Collection elements) { Element body = DocumentHelper.createElement("body"); body.addAttribute("xmlns", "http://jabber.org/protocol/httpbind"); @@ -237,11 +262,11 @@ return isSecure; } - public void addSessionCloseListener(SessionCloseListener listener) { + public void addSessionCloseListener(SessionListener listener) { listeners.add(listener); } - public void removeSessionCloseListener(SessionCloseListener listener) { + public void removeSessionCloseListener(SessionListener listener) { listeners.remove(listener); } @@ -252,4 +277,8 @@ public int getInactivityTimeout() { return inactivityTimeout; } + + public int getConnectionCount() { + return connectionQueue.size(); + } } diff --git a/src/java/org/jivesoftware/multiplexer/net/http/HttpSessionManager.java b/src/java/org/jivesoftware/multiplexer/net/http/HttpSessionManager.java index aff80e8..94fd110 100644 --- a/src/java/org/jivesoftware/multiplexer/net/http/HttpSessionManager.java +++ b/src/java/org/jivesoftware/multiplexer/net/http/HttpSessionManager.java @@ -118,7 +118,22 @@ HttpSession.addSession(streamID, session); // Send to the server that a new client session has been created serverSurrogate.clientSessionCreated(streamID); - session.addSessionCloseListener(new SessionCloseListener() { + session.addSessionCloseListener(new SessionListener() { + public void connectionOpened(Session session, HttpConnection connection) { + if (session instanceof HttpSession) { + timer.stop((HttpSession) session); + } + } + + public void connectionClosed(Session session, HttpConnection connection) { + if(session instanceof HttpSession) { + HttpSession http = (HttpSession) session; + if(http.getConnectionCount() <= 0) { + timer.reset(http); + } + } + } + public void sessionClosed(Session session) { HttpSession.removeSession(session.getStreamID()); serverSurrogate.clientSessionClosed(session.getStreamID()); @@ -163,9 +178,9 @@ } public HttpConnection forwardRequest(long rid, HttpSession session, boolean isSecure, - Element rootNode) throws HttpBindException + Element rootNode) throws HttpBindException, + HttpConnectionClosedException { - timer.reset(session); //noinspection unchecked List elements = rootNode.elements(); @@ -184,23 +199,27 @@ private Map sessionMap = new HashMap(); - public void reset(HttpSession session) { + public void stop(HttpSession session) { InactivityTimeoutTask task = sessionMap.remove(session.getStreamID()); if(task != null) { session.removeSessionCloseListener(task); task.cancel(); } + } + + public void reset(HttpSession session) { + stop(session); if(session.isClosed()) { return; } - task = new InactivityTimeoutTask(session); + InactivityTimeoutTask task = new InactivityTimeoutTask(session); schedule(task, session.getInactivityTimeout() * 1000); session.addSessionCloseListener(task); sessionMap.put(session.getStreamID(), task); } } - private class InactivityTimeoutTask extends TimerTask implements SessionCloseListener { + private class InactivityTimeoutTask extends TimerTask implements SessionListener { private Session session; public InactivityTimeoutTask(Session session) { @@ -211,6 +230,12 @@ session.close(); } + public void connectionOpened(Session session, HttpConnection connection) { + } + + public void connectionClosed(Session session, HttpConnection connection) { + } + public void sessionClosed(Session session) { this.cancel(); } diff --git a/src/java/org/jivesoftware/multiplexer/net/http/SessionCloseListener.java b/src/java/org/jivesoftware/multiplexer/net/http/SessionCloseListener.java deleted file mode 100644 index 8d724fb..0000000 --- a/src/java/org/jivesoftware/multiplexer/net/http/SessionCloseListener.java +++ /dev/null @@ -1,18 +0,0 @@ -/** - * $RCSfile: $ - * $Revision: $ - * $Date: $ - * - * Copyright (C) 2006 Jive Software. All rights reserved. - * This software is the proprietary information of Jive Software. Use is subject to license terms. - */ -package org.jivesoftware.multiplexer.net.http; - -import org.jivesoftware.multiplexer.Session; - -/** - * - */ -public interface SessionCloseListener { - public void sessionClosed(Session session); -} diff --git a/src/java/org/jivesoftware/multiplexer/net/http/SessionListener.java b/src/java/org/jivesoftware/multiplexer/net/http/SessionListener.java new file mode 100644 index 0000000..699841a --- /dev/null +++ b/src/java/org/jivesoftware/multiplexer/net/http/SessionListener.java @@ -0,0 +1,22 @@ +/** + * $RCSfile: $ + * $Revision: $ + * $Date: $ + * + * Copyright (C) 2006 Jive Software. All rights reserved. + * This software is the proprietary information of Jive Software. Use is subject to license terms. + */ +package org.jivesoftware.multiplexer.net.http; + +import org.jivesoftware.multiplexer.Session; + +/** + * + */ +public interface SessionListener { + public void connectionOpened(Session session, HttpConnection connection); + + public void connectionClosed(Session session, HttpConnection connection); + + public void sessionClosed(Session session); +}