I'm not sure how java internals of cfloop/collection work, but chances
are it's dangerous to loop through a collection you are deleting/adding
items to/from.
Perhaps change to CFLOOP list=StructKeyList(application.UsersInof) and
then retreive the item if it's there...
Also, How do you keep the person "online"... it seems like the following
undesirable timeline is possible:
8:00 User logs in, gets a now() timestamp
8:14 User hits a page. Since still has a timestamp, nothing happens
8:16 User is deleted, since the 8:00 stamp expired, even though user hit
2 minutes ago...
You should update a user's timestamp on each hit... I'd write it like
this:
when user logs in,
<Cfset Session.Stamp=structnew()>
<Cfset session.stamp.last=now()>
<Cfset application.UsersInfo[session.userid]=session.stamp>
Then whenever a user hits the page, you have
<Cfif session.isloggedin and isdefined("Session.stamp.last")>
<Cfset session.stamp.last=now()>
</cfif>
Since session.stamp is a reference to a struct, which also exists in
application.usersinfo, it doesnt get destroyed with the session....
Just a thought
HTH
d
Dov Katz
Enterprise & Client Technology
Morgan Stanley
<mailto:[EMAIL PROTECTED]>
_____
From: Sung Woo [mailto:[EMAIL PROTECTED]
Sent: Wednesday, September 15, 2004 9:15 AM
To: CF-Talk
Subject: Users Online, Take 2
So I've finally gotten around to rewriting the "who is online?" portion
of my site, and it turns out that I didn't have to do much rewriting at
all. The script below was using CFID to keep track, which, as many
people pointed out, was not a good idea. I keep a session variable
(session.UserID) in my application, so this was a much better idea. So
the script is as follows:
<!--- keep a list of online users --->
<cfif Session.LoggedIn>
<cfif NOT IsDefined("Application.UsersInfo")>
<cflock timeout="15" scope="APPLICATION" type="EXCLUSIVE">
<cfif NOT IsDefined("Application.UsersInfo")>
<cfset Application.UsersInfo = StructNew()>
</cfif>
</cflock>
</cfif>
<cfif NOT StructKeyExists(Application.UsersInfo, session.UserID)>
<cflock scope="APPLICATION" type="EXCLUSIVE" timeout="15">
<cfif NOT StructKeyExists(Application.UsersInfo,
session.UserID)>
<cfset StructInsert(Application.UsersInfo, session.UserID,
now())>
</cfif>
</cflock>
</cfif>
<cfloop collection="#Application.UsersInfo#" item="itmUser">
<cflock name="session_lock_#itmUser#" timeout="15">
<cfif StructKeyExists(Application.UsersInfo, itmUser)>
<cfif DateDiff("n", Application.UsersInfo[itmUser], Now())
GT 15>
<cfset StructDelete(Application.UsersInfo, itmUser)>
</cfif>
</cfif>
</cflock>
</cfloop>
</cfif>
My question involves the StructDelete portion of the code, namely:
<cfloop collection="#Application.UsersInfo#" item="itmUser">
<cflock name="session_lock_#itmUser#" timeout="15">
<cfif StructKeyExists(Application.UsersInfo, itmUser)>
<cfif DateDiff("n", Application.UsersInfo[itmUser], Now())
GT 15>
<cfset StructDelete(Application.UsersInfo, itmUser)>
</cfif>
</cfif>
</cflock>
</cfloop>
I have this script in the application.cfm file, which means this loop is
activated with every single click. Sure, it isn't that much load, but I
don't see any reason why this should kick in so often. So I cut it out
of the application.cfm file and created a separate file, called
cleanup_online_users.cfm. Then I used Scheduled Tasks to schedule this
snippet of code -- and it doesn't work. It's very strange -- if I run
it manually, it doesn't work, either. However, if I manually run it AND
THEN force a refresh, it works. I was wondering if CF was somehow
caching this page, so I changed the page to this:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>cleanup</title>
<META HTTP-EQUIV="Pragma" CONTENT="no-cache">
<META HTTP-EQUIV="Expires" CONTENT="-1">
</head>
<body>
<!--- cleanup_online_users.cfm --->
<cfloop collection="#Application.UsersInfo#" item="itmUser">
<cflock name="session_lock_#itmUser#" timeout="15">
<cfif StructKeyExists(Application.UsersInfo, itmUser)>
<cfif DateDiff("n", Application.UsersInfo[itmUser], Now())
GT 15>
<cfset StructDelete(Application.UsersInfo, itmUser)>
</cfif>
</cfif>
</cflock>
</cfloop>
</body>
</html>
Still doesn't work. The only way to make it work is if I load it
manually and then refresh. What am I doing wrong?
I'm running Win2K & CFMX 6.1.
- Sung
_____
[Todays Threads]
[This Message]
[Subscription]
[Fast Unsubscribe]
[User Settings]
[Donations and Support]
- Users Online, Take 2 Sung Woo
- Re: Users Online, Take 2 Katz, Dov B (IT)
- Re: Users Online, Take 2 Sung Woo
- Re: Users Online, Take 2 Sung Woo