Re: onSessionStart / onSessionEnd
"kRAkEn/gORe" <[email protected]>
| Newsgroups | gmane.comp.java.helma.general |
|---|---|
| Message-ID | <[email protected]> |
yeah i know, this is the update version. it works on my side, and a new session ISN't created for every request. i've tested widely (adding stuff to session.data in the onSessionStart) and it works ok. i can see it calling on a new request that don't have a session already allocated, and after the timeout, it calls the cleanup onSessionEnd. you can't put complex things in that, but i just needed a function to get told when a new session starts so i can fill session things up (basically a map engine), and let the map engine clean up when the session end, freeing up the remaining files previously allocated by the user lucio On 6/6/07, Hannes Wallnoefer <[email protected]> wrote: > 2007/5/31, kRAkEn/gORe <[email protected]>: > > just wondering, any possibility to have these added in the repository ? > > i need to know when a new session is started up and when it is > > released (freeing any associated maps generated by my map engine). > > The problem I see with your patch is that the functions are not > invoked with the actual session. That's because > RequestEvaluator.invokeInternal() (and invokeDirectFunction(), which > would probably be a better choice in this case, because it runs the > function in the caller thread) only install a dummy session in the JS > scope (only invokeHttp() uses an actual HTTP user session). > > The easiest way to fix this would be to simply pass the session as > argument to the function. > > Apart from that, I'm still unsure about the additional overhead of > these two callbacks. Helma creates a new session for each request, > regardless of whether it is actually accessed. I'd really like to get > an idea about session fluctuation on some real site like antville.org. > > What about other users? Does anybody else have a need for these callbacks? > > hannes > > > thanx > > > > _______________________________________________ > > Helma-user mailing list > > [email protected] > > http://helma.org/mailman/listinfo/helma-user > > > > > > > _______________________________________________ > Helma-user mailing list > [email protected] > http://helma.org/mailman/listinfo/helma-user > _______________________________________________ Helma-user mailing list [email protected] http://helma.org/mailman/listinfo/helma-user
SessionManager.java
(text/x-java, 8.6 KB)
/*
* Helma License Notice
*
* The contents of this file are subject to the Helma License
* Version 2.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://adele.helma.org/download/helma/license.txt
*
* Copyright 1998-2003 Helma Software. All Rights Reserved.
*
* $RCSfile: SessionManager.java,v $
* $Author: hannes $
* $Revision: 1.5 $
* $Date: 2006/05/24 12:29:09 $
*/
package helma.framework.core;
import helma.objectmodel.INode;
import helma.objectmodel.db.Node;
import helma.scripting.ScriptingEngine;
import java.util.*;
import java.io.*;
public class SessionManager {
protected Hashtable sessions;
protected Application app;
public SessionManager() {
sessions = new Hashtable();
}
public void init(Application app) {
this.app = app;
}
public void shutdown() {
sessions.clear();
}
public Session createSession(String sessionId) {
Session session = getSession(sessionId);
if (session == null) {
session = new Session(sessionId, app);
sessions.put(sessionId, session);
// as first thing, invoke global onSessionStart() function
RequestEvaluator eval = null;
try {
eval = app.getEvaluator();
SessionBean bean = new SessionBean (session);
Object[] param = {bean};
eval.invokeInternal(null, "onSessionBegin", param); // RequestEvaluator.EMPTY_ARGS);
} catch (Exception xcept) {
app.logError("Error in onSessionBegin()", xcept);
} finally {
app.releaseEvaluator(eval);
}
}
return session;
}
public Session getSession(String sessionId) {
if (sessionId == null)
return null;
return (Session) sessions.get(sessionId);
}
/**
* Return the whole session map. We return a clone of the table to prevent
* actual changes from the table itself, which is managed by the application.
* It is safe and allowed to manipulate the session objects contained in the table, though.
*/
public Map getSessions() {
return (Map) sessions.clone();
}
/**
* Returns the number of currenty active sessions.
*/
public int countSessions() {
return sessions.size();
}
/**
* Remove the session from the sessions-table and logout the user.
*/
public void discardSession(Session session) {
logoutSession(session);
// as first thing, invoke global onSessionStart() function
RequestEvaluator eval = null;
try {
eval = app.getEvaluator();
eval.invokeInternal(null, "onSessionEnd", RequestEvaluator.EMPTY_ARGS);
} catch (Exception xcept) {
app.logError("Error in onSessionEnd()", xcept);
} finally {
app.releaseEvaluator(eval);
}
sessions.remove(session.getSessionId());
}
/**
* Log in a user given his or her user name and password.
*/
public boolean loginSession(String uname, String password, Session session) {
// Check the name/password of a user and log it in to the current session
if (uname == null) {
return false;
}
uname = uname.toLowerCase().trim();
if ("".equals(uname)) {
return false;
}
try {
INode users = app.getUserRoot();
Node unode = (Node) users.getChildElement(uname);
String pw = unode.getString("password");
if ((pw != null) && pw.equals(password)) {
// let the old user-object forget about this session
logoutSession(session);
session.login(unode);
return true;
}
} catch (Exception x) {
return false;
}
return false;
}
/**
* Log out a session from this application.
*/
public void logoutSession(Session session) {
session.logout();
}
/**
* Return an array of <code>SessionBean</code> objects currently associated with a given
* Helma user.
*/
public List getSessionsForUsername(String username) {
ArrayList list = new ArrayList();
if (username == null) {
return list;
}
Enumeration e = sessions.elements();
while (e.hasMoreElements()) {
Session s = (Session) e.nextElement();
if (s != null && username.equals(s.getUID())) {
// append to list if session is logged in and fits the given username
list.add(new SessionBean(s));
}
}
return list;
}
/**
* Return a list of Helma nodes (HopObjects - the database object representing the user,
* not the session object) representing currently logged in users.
*/
public List getActiveUsers() {
ArrayList list = new ArrayList();
for (Enumeration e = sessions.elements(); e.hasMoreElements();) {
Session s = (Session) e.nextElement();
if (s != null && s.isLoggedIn()) {
// returns a session if it is logged in and has not been
// returned before (so for each logged-in user is only added once)
INode node = s.getUserNode();
// we check again because user may have been logged out between the first check
if (node != null && !list.contains(node)) {
list.add(node);
}
}
}
return list;
}
/**
* Dump session state to a file.
*
* @param f the file to write session into, or null to use the default sesssion store.
*/
public void storeSessionData(File f, ScriptingEngine engine) {
if (f == null) {
f = new File(app.dbDir, "sessions");
}
try {
OutputStream ostream = new BufferedOutputStream(new FileOutputStream(f));
ObjectOutputStream p = new ObjectOutputStream(ostream);
synchronized (sessions) {
p.writeInt(sessions.size());
for (Enumeration e = sessions.elements(); e.hasMoreElements();) {
try {
engine.serialize(e.nextElement(), p);
// p.writeObject(e.nextElement());
} catch (NotSerializableException nsx) {
// not serializable, skip this session
app.logError("Error serializing session.", nsx);
}
}
}
p.flush();
ostream.close();
app.logEvent("stored " + sessions.size() + " sessions in file");
} catch (Exception e) {
app.logError("error storing session data.", e);
}
}
/**
* loads the serialized session table from a given file or from dbdir/sessions
*/
public void loadSessionData(File f, ScriptingEngine engine) {
if (f == null) {
f = new File(app.dbDir, "sessions");
}
// compute session timeout value
int sessionTimeout = 30;
try {
sessionTimeout = Math.max(0,
Integer.parseInt(app.getProperty("sessionTimeout",
"30")));
} catch (Exception ignore) {
System.out.println(ignore.toString());
}
long now = System.currentTimeMillis();
try {
// load the stored data:
InputStream istream = new BufferedInputStream(new FileInputStream(f));
ObjectInputStream p = new ObjectInputStream(istream);
int size = p.readInt();
int ct = 0;
Hashtable newSessions = new Hashtable();
while (ct < size) {
Session session = (Session) engine.deserialize(p);
if ((now - session.lastTouched()) < (sessionTimeout * 60000)) {
session.setApp(app);
newSessions.put(session.getSessionId(), session);
}
ct++;
}
p.close();
istream.close();
sessions = newSessions;
app.logEvent("loaded " + newSessions.size() + " sessions from file");
} catch (FileNotFoundException fnf) {
// suppress error message if session file doesn't exist
} catch (Exception e) {
app.logError("error loading session data.", e);
}
}
}