|
Tomcat example source code file (CometConnectionManagerValve.java)
The Tomcat CometConnectionManagerValve.java source code/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.catalina.valves; import java.io.IOException; import java.util.Iterator; import java.util.concurrent.ConcurrentHashMap; import javax.servlet.ServletException; import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSessionEvent; import javax.servlet.http.HttpSessionListener; import org.apache.catalina.CometEvent; import org.apache.catalina.Context; import org.apache.catalina.Lifecycle; import org.apache.catalina.LifecycleEvent; import org.apache.catalina.LifecycleException; import org.apache.catalina.LifecycleListener; import org.apache.catalina.connector.CometEventImpl; import org.apache.catalina.connector.Request; import org.apache.catalina.connector.Response; import org.apache.catalina.util.LifecycleSupport; import org.apache.catalina.util.StringManager; /** * <p>Implementation of a Valve that tracks Comet connections, and closes them * when the associated session expires or the webapp is reloaded.</p> * * <p>This Valve should be attached to a Context. * * @author Remy Maucherat * @version $Revision: 467222 $ $Date: 2006-10-24 05:17:11 +0200 (mar., 24 oct. 2006) $ */ public class CometConnectionManagerValve extends ValveBase implements Lifecycle, HttpSessionListener, LifecycleListener { // ----------------------------------------------------- Instance Variables /** * The descriptive information related to this implementation. */ protected static final String info = "org.apache.catalina.valves.CometConnectionManagerValve/1.0"; /** * The string manager for this package. */ protected StringManager sm = StringManager.getManager(Constants.Package); /** * The lifecycle event support for this component. */ protected LifecycleSupport lifecycle = new LifecycleSupport(this); /** * Has this component been started yet? */ protected boolean started = false; /** * Connection list. */ protected ConcurrentHashMap<String, ConnectionInfo[]> connections = new ConcurrentHashMap<String, ConnectionInfo[]>(); // ------------------------------------------------------------- Properties // ------------------------------------------------------ Lifecycle Methods /** * Add a lifecycle event listener to this component. * * @param listener The listener to add */ public void addLifecycleListener(LifecycleListener listener) { lifecycle.addLifecycleListener(listener); } /** * Get the lifecycle listeners associated with this lifecycle. If this * Lifecycle has no listeners registered, a zero-length array is returned. */ public LifecycleListener[] findLifecycleListeners() { return lifecycle.findLifecycleListeners(); } /** * Remove a lifecycle event listener from this component. * * @param listener The listener to add */ public void removeLifecycleListener(LifecycleListener listener) { lifecycle.removeLifecycleListener(listener); } /** * Prepare for the beginning of active use of the public methods of this * component. This method should be called after <code>configure(), * and before any of the public methods of the component are utilized. * * @exception LifecycleException if this component detects a fatal error * that prevents this component from being used */ public void start() throws LifecycleException { // Validate and update our current component state if (started) throw new LifecycleException (sm.getString("semaphoreValve.alreadyStarted")); lifecycle.fireLifecycleEvent(START_EVENT, null); started = true; if (container instanceof Context) { ((Lifecycle) container).addLifecycleListener(this); } } /** * Gracefully terminate the active use of the public methods of this * component. This method should be the last one called on a given * instance of this component. * * @exception LifecycleException if this component detects a fatal error * that needs to be reported */ public void stop() throws LifecycleException { // Validate and update our current component state if (!started) throw new LifecycleException (sm.getString("semaphoreValve.notStarted")); lifecycle.fireLifecycleEvent(STOP_EVENT, null); started = false; if (container instanceof Context) { ((Lifecycle) container).removeLifecycleListener(this); } // The webapp is getting stopped, so all current connections // should be closed // Close all Comet connections associated with this session // Note: this will only be done if the container was not a Context // (otherwise, this needs to be done before stop, as the servlet would // be deallocated already) Iterator<ConnectionInfo[]> iterator = connections.values().iterator(); while (iterator.hasNext()) { ConnectionInfo[] connectionInfos = iterator.next(); if (connectionInfos != null) { for (int i = 0; i < connectionInfos.length; i++) { ConnectionInfo connectionInfo = connectionInfos[i]; try { connectionInfo.event.close(); } catch (Exception e) { container.getLogger().warn(sm.getString("cometConnectionManagerValve.event"), e); } } } } connections.clear(); } public void lifecycleEvent(LifecycleEvent event) { if (event.getType() == Lifecycle.BEFORE_STOP_EVENT) { // The webapp is getting stopped, so all current connections // should be closed // Close all Comet connections associated with this session Iterator<ConnectionInfo[]> iterator = connections.values().iterator(); while (iterator.hasNext()) { ConnectionInfo[] connectionInfos = iterator.next(); if (connectionInfos != null) { for (int i = 0; i < connectionInfos.length; i++) { ConnectionInfo connectionInfo = connectionInfos[i]; try { ((CometEventImpl) connectionInfo.event).setEventType(CometEvent.EventType.END); ((CometEventImpl) connectionInfo.event).setEventSubType(CometEvent.EventSubType.WEBAPP_RELOAD); getNext().event(connectionInfo.request, connectionInfo.response, connectionInfo.event); connectionInfo.event.close(); } catch (Exception e) { container.getLogger().warn(sm.getString("cometConnectionManagerValve.event"), e); } } } } connections.clear(); } } // --------------------------------------------------------- Public Methods /** * Return descriptive information about this Valve implementation. */ public String getInfo() { return (info); } /** * Register requests for tracking, whenever needed. * * @param request The servlet request to be processed * @param response The servlet response to be created * * @exception IOException if an input/output error occurs * @exception ServletException if a servlet error occurs */ public void invoke(Request request, Response response) throws IOException, ServletException { // Perform the request getNext().invoke(request, response); if (request.isComet() && !response.isClosed()) { // Start tracking this connection, since this is a // begin event, and Comet mode is on HttpSession session = request.getSession(true); ConnectionInfo newConnectionInfo = new ConnectionInfo(); newConnectionInfo.request = request; newConnectionInfo.response = response; newConnectionInfo.event = request.getEvent(); synchronized (session) { String id = session.getId(); ConnectionInfo[] connectionInfos = connections.get(id); if (connectionInfos == null) { connectionInfos = new ConnectionInfo[1]; connectionInfos[0] = newConnectionInfo; connections.put(id, connectionInfos); } else { ConnectionInfo[] newConnectionInfos = new ConnectionInfo[connectionInfos.length + 1]; for (int i = 0; i < connectionInfos.length; i++) { newConnectionInfos[i] = connectionInfos[i]; } newConnectionInfos[connectionInfos.length] = newConnectionInfo; connections.put(id, newConnectionInfos); } } } } /** * Use events to update the connection state. * * @param request The servlet request to be processed * @param response The servlet response to be created * * @exception IOException if an input/output error occurs * @exception ServletException if a servlet error occurs */ public void event(Request request, Response response, CometEvent event) throws IOException, ServletException { // Perform the request boolean ok = false; try { getNext().event(request, response, event); ok = true; } finally { if (!ok || response.isClosed() || (event.getEventType() == CometEvent.EventType.END) || (event.getEventType() == CometEvent.EventType.ERROR && !(event.getEventSubType() == CometEvent.EventSubType.TIMEOUT))) { // Remove from tracked list, the connection is done HttpSession session = request.getSession(true); synchronized (session) { ConnectionInfo[] connectionInfos = connections.get(session.getId()); if (connectionInfos != null) { boolean found = false; for (int i = 0; !found && (i < connectionInfos.length); i++) { found = (connectionInfos[i].request == request); } if (found) { ConnectionInfo[] newConnectionInfos = new ConnectionInfo[connectionInfos.length - 1]; int pos = 0; for (int i = 0; i < connectionInfos.length; i++) { if (connectionInfos[i].request != request) { newConnectionInfos[pos++] = connectionInfos[i]; } } connections.put(session.getId(), newConnectionInfos); } } } } } } public void sessionCreated(HttpSessionEvent se) { } public void sessionDestroyed(HttpSessionEvent se) { // Close all Comet connections associated with this session ConnectionInfo[] connectionInfos = connections.remove(se.getSession().getId()); if (connectionInfos != null) { for (int i = 0; i < connectionInfos.length; i++) { ConnectionInfo connectionInfo = connectionInfos[i]; try { ((CometEventImpl) connectionInfo.event).setEventType(CometEvent.EventType.END); ((CometEventImpl) connectionInfo.event).setEventSubType(CometEvent.EventSubType.SESSION_END); getNext().event(connectionInfo.request, connectionInfo.response, connectionInfo.event); connectionInfo.event.close(); } catch (Exception e) { container.getLogger().warn(sm.getString("cometConnectionManagerValve.event"), e); } } } } // --------------------------------------------- ConnectionInfo Inner Class protected class ConnectionInfo { public CometEvent event; public Request request; public Response response; } } Other Tomcat examples (source code examples)Here is a short list of links related to this Tomcat CometConnectionManagerValve.java source code file: |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.