Who's online script using coldfusion

Does anyone know how to write a script in coldfusion so I can show my visitors who's online. I want the sever to tell me who's online once they logged in. Kind of like what you would see on Myspace.com.
overcolorAsked:
Who is Participating?
 
SidFishesConnect With a Mentor Commented:
if you read the code examples i provided you'll see which section goes where

but I'll give it to you again

btw...for future reference, I and many others use the "Guru on this subject." which you set up your question with to tailor your answer. If you say you're a guru on something you are often going to get an answer that leaves out the basics as we assume you'll know what we're talking about then we go around and around covering the basics of cf (or whatever) so we can get the code working.

IN APPLICATION.CFM
<cfapplication  sessiontimeout="20" name="TestB" sessionManagement="true">
<!--- Test for existence of UserInfo and create if necessary  --->
 <cflock timeout="15" scope="APPLICATION" type="EXCLUSIVE">
    <cfif NOT isDefined("Application.UsersInfo")>
          <cfset Application.UsersInfo = StructNew()>
    </cfif>
</cflock>
 
<cfparam name="session.id" default="">
 
<cflock scope="APPLICATION" type="EXCLUSIVE" timeout="15">
<!---
since application.cfm is called on every page load if session.id has a 
value that means the client is still here so set variable --->
	<cfset stillHere = session.id>
	<cflock scope="APPLICATION" type="EXCLUSIVE" timeout="15">
		<cfif StructKeyExists(Application.UsersInfo, stillhere)>
			<!--- because the client is still here update the struct with the last
			  time the client hit a page  --->
			<cfset temp = StructUPdate(Application.UsersInfo,stillhere, now())>
		</cfif>
	</cflock>
	
  <cfloop collection="#Application.UsersInfo#" item="uName">
	<!--- every time the page is called we look for values in the struct which are larger than 20 minutes 
	(or whatever session length you want) and delete them as their sessions will have expired.   --->
	
	<cfif Evaluate(DateDiff("n", StructFind(Application.UsersInfo, uName), Now())) GT 4>
    <cfset StructDelete(Application.UsersInfo, uName)>
</cfif>
 </cfloop>
</cflock>
 
END APPLiCATION.CFM CODE
 
IN YOUR LOGIN POROCESSING CODE
 
<cfif isDefined('form.uName')>
 
<cfquery name="checkLogIn" datasource="mydsn">
select MemberID from mytbl where username=#form.uName# and password = #form.password#
</cfquery>
 
<cfif checklogin.recordcount eq 1> 
        <!--- create new user info for the struct --->
        <cflock name="#CreateUUID()#" timeout="15" type="EXCLUSIVE">
             <cfset user_cfid = Evaluate(CFID) & "," & checklogin.MemberID>
                 <cfset user_time = Now()>
        </cflock>
        <!--- set a session id so we can use it to verify that this session is still active in application.cfm --->
        <cfset session.id = user_cfid> 
        <cflock scope="APPLICATION" type="EXCLUSIVE" timeout="15">
        <!--- If the user does not exist in the struct, insert it --->
         <cfif NOT StructKeyExists(Application.UsersInfo, user_cfid)>
                <cfset temp = StructInsert(Application.UsersInfo, user_cfid, user_time)>
         </cfif>
        </cflock>
 
<cfelse>
Login failure
</cfif>
</cfif>
 
END LOGIN PROCESSING CODE
 
IN A PAGE CALLED WHOSONLINE.cfm
 
<cflock scope="APPLICATION" type="EXCLUSIVE" timeout="10">
    <cfoutput>
        Users Online : #StructCount(Application.UsersInfo)#<br>
        <cfset keysToStruct = StructKeyList(Application.UsersInfo)>
    
        <cfloop collection="#Application.UsersInfo#" item="uName">
                <cfif listlast(Uname) eq listLast(session.id)> 
                <strong>#listlast(Uname)#</strong> is ME! 
                
                <cfelse>
                #listlast(Uname)# - Last Activity : #Dateformat(structfind(Application.UsersInfo,uname), "hh:mm:ss")#<br>
                </cfif> 
        </cfloop>               
                
    </cfoutput>
</cflock>
 
END WHOSONLINE.cfm
 
Then on each page you want the WHO' S ONLINE 
 
<cfinclude template="whosonline.cfm">

Open in new window

0
 
mihaimmCommented:
Rather simple... but in the same time not that simple. You need an extra column in your USERS table: isLoggedIn (0/1).
When the user logs in you set the column 1.
When the user logs out or the session expires you set the column to 0.
Then it's a matter of a simple query in the database: select * from USERS where isLoggedIn=1
0
 
SidFishesCommented:
I wouldn't go that way (altho you can)


add this to you application.cfm

 <cflock timeout="15" scope="APPLICATION" type="EXCLUSIVE">
    <cfif NOT isDefined("Application.UsersInfo")>
          <cfset Application.UsersInfo = StructNew()>
    </cfif>
</cflock>


<cflock scope="APPLICATION" type="EXCLUSIVE" timeout="15">
 <cfloop collection="#Application.UsersInfo#" item="itmUser">
  <cfif
   Evaluate(DateDiff("n", StructFind(Application.UsersInfo, itmUser), Now())) GT 10>
    <cfset StructDelete(Application.UsersInfo, itmUser)>
  </cfif>
 </cfloop>
</cflock>

then create a test page


<cfif isDefined('form.uName')>
 
<cflock name="#CreateUUID()#" timeout="15" type="EXCLUSIVE">
      <cfset user_uName = form.uName>
      <cfset user_time = Now()>
</cflock>
 
 
<cflock scope="APPLICATION" type="EXCLUSIVE" timeout="15">
 <cfif NOT StructKeyExists(Application.UsersInfo, user_uName)>
  <cfset temp = StructInsert(Application.UsersInfo, user_uName, user_time)>
 </cfif>
</cflock>
 </cfif>
 

 
<form method="post" action="test.cfm">
Username: <input type="Text" name="uName">
<input type="submit">
</form>
 

<cflock scope="APPLICATION" type="EXCLUSIVE" timeout="10">
    <cfoutput>
        Users Online : #StructCount(Application.UsersInfo)#<br>
            
            <cfset temp = structkeylist(Application.UsersInfo)>
            
            #replace(temp, ",","<br>","all")#
            
    </cfoutput>
</cflock>

This page just posts back to itself in your real app you'd add the user name to the UsersInfo Struct after log in has be verified. To test just enter a name, submit and repeat...




0
The 14th Annual Expert Award Winners

The results are in! Meet the top members of our 2017 Expert Awards. Congratulations to all who qualified!

 
mihaimmCommented:
With a database column you can get the info from any other application, not only from the CF one.
Also... you're just faking the "who's online" functionality :o.
0
 
SidFishesCommented:
here some revised code (no faking here...this does work)





in application.cfm
 
<cfapplication  sessiontimeout="20" name="TestB" sessionManagement="true">
<!--- Test for existence of UserInfo and create if necessary  --->
 <cflock timeout="15" scope="APPLICATION" type="EXCLUSIVE">
    <cfif NOT isDefined("Application.UsersInfo")>
          <cfset Application.UsersInfo = StructNew()>
    </cfif>
</cflock>
 
<cfparam name="session.id" default="">
 
<cflock scope="APPLICATION" type="EXCLUSIVE" timeout="15">
<!---
since application.cfm is called on every page load if session.id has a 
value that means the client is still here so set variable --->
	<cfset stillHere = session.id>
	<cflock scope="APPLICATION" type="EXCLUSIVE" timeout="15">
		<cfif StructKeyExists(Application.UsersInfo, stillhere)>
			<!--- because the client is still here update the struct with the last
			  time the client hit a page  --->
			<cfset temp = StructUPdate(Application.UsersInfo,stillhere, now())>
		</cfif>
	</cflock>
	
  <cfloop collection="#Application.UsersInfo#" item="uName">
	<!--- every time the page is called we look for values in the struct which are larger than 20 minutes 
	(or whatever session length you want) and delete them as their sessions will have expired.   --->
	
	<cfif Evaluate(DateDiff("n", StructFind(Application.UsersInfo, uName), Now())) GT 4>
    <cfset StructDelete(Application.UsersInfo, uName)>
</cfif>
 </cfloop>
</cflock>
 
test.cfm
 
 
<cfif isDefined('form.uName')>
	<!--- create new user info for the struct --->
	<cflock name="#CreateUUID()#" timeout="15" type="EXCLUSIVE">
	     <cfset user_cfid = Evaluate(CFID) & "," & form.uName>
		 <cfset user_time = Now()>
	</cflock>
	<!--- set a session id so we can use it to verify that this session is still active in application.cfm --->
	<cfset session.id = user_cfid> 
	<cflock scope="APPLICATION" type="EXCLUSIVE" timeout="15">
	<!--- If the user does not exist in the struct, insert it --->
	 <cfif NOT StructKeyExists(Application.UsersInfo, user_cfid)>
	  	<cfset temp = StructInsert(Application.UsersInfo, user_cfid, user_time)>
	 </cfif>
	</cflock>
 </cfif>
 
<form method="post" action="index.cfm">
Username: <input type="Text" name="uName">
<input type="submit">
</form> 
 
 
<cflock scope="APPLICATION" type="EXCLUSIVE" timeout="10">
    <cfoutput>
        Users Online : #StructCount(Application.UsersInfo)#<br>
	<cfset keysToStruct = StructKeyList(Application.UsersInfo)>
    
	<cfloop collection="#Application.UsersInfo#" item="uName">
		<cfif listlast(Uname) eq listLast(session.id)> 
		<strong>#listlast(Uname)#</strong> is ME! 
		
		<cfelse>
		#listlast(Uname)# - Last Activity : #Dateformat(structfind(Application.UsersInfo,uname), "hh:mm:ss")#<br>
		</cfif> 
	</cfloop>		
		
    </cfoutput>
</cflock>

Open in new window

0
 
SidFishesCommented:
two corrections

<cfset keysToStruct = StructKeyList(Application.UsersInfo)> can be removed (is not needed)


dateformat sb
#timeformat(structfind(Application.UsersInfo,uname), "hh:mm:ss")#
0
 
SidFishesCommented:
oh and while i said "sessions greater than 20 minutes" I've actually got the delete occurring after 4 minutes here


<cfif Evaluate(DateDiff("n", StructFind(Application.UsersInfo, uName), Now())) GT 4>

just change it to

<cfif Evaluate(DateDiff("n", StructFind(Application.UsersInfo, uName), Now())) GT 20> (or whatever)
0
 
overcolorAuthor Commented:
When they log in the unique Id i use is called "MembersID" can you show me where I would write that in the code. And I would like the system to check every 30min. Can you show me that also?  

Thank You
0
 
SidFishesCommented:
Obviously your login code will be different but basically you just authenticate and pass the memberid to the struct (in this case as checkLogin.MemberID


for a 30 minute timeout just change GT 20 to GT 30

just so we're clear the code doesn't check every 20 or 30 minutes, it checks on every page request from all users

if it finds that the request client  (your member) is NOT in the struct, it adds them with a timestamp
if it finds they ARE in the struct it updates their entry with a new timestamp
if it finds that they ARE in the struct but the timestamp is older than x minutes then they are deleted.
<cfif isDefined('form.uName')>
 
<cfquery name="checkLogIn" datasource="mydsn">
select MemberID from mytbl where username=#form.uName# and password = #form.password#
</cfquery>
 
<cfif checklogin.recordcount eq 1> 
	<!--- create new user info for the struct --->
	<cflock name="#CreateUUID()#" timeout="15" type="EXCLUSIVE">
	     <cfset user_cfid = Evaluate(CFID) & "," & checklogin.MemberID>
		 <cfset user_time = Now()>
	</cflock>
	<!--- set a session id so we can use it to verify that this session is still active in application.cfm --->
	<cfset session.id = user_cfid> 
	<cflock scope="APPLICATION" type="EXCLUSIVE" timeout="15">
	<!--- If the user does not exist in the struct, insert it --->
	 <cfif NOT StructKeyExists(Application.UsersInfo, user_cfid)>
	  	<cfset temp = StructInsert(Application.UsersInfo, user_cfid, user_time)>
	 </cfif>
	</cflock>
 
<cfelse>
Login failure
</cfif>
</cfif>

Open in new window

0
 
overcolorAuthor Commented:
Can you provide me with the code I would use to output to show who is logged in. Also the above code I should put in my application.cfm correct?
0
 
overcolorAuthor Commented:
Thanks.. I never knew that. I always thought I was doing something wrong.

I'll try the code tonight.
0
 
SidFishesCommented:
did you get a chance to try this? Need more help?
0
 
overcolorAuthor Commented:
Yes I tried the code, I think everything works great, but on the whosonline.cfm page. I see it telling me I'm online i want to adjust it to tell me all of the members that are online. When I put in my code it comes up on my login for how ever members are online. So next to my name it says online twice because there are two members logged in. But next to the other members name it not telling me they are logged in. I think it is because of the loop. I want to know if there is a way to have it show all of the member that are online next to there name not just mind.

Ex: Tom: Online Online
      Tim:

I want it to say
Tom: Online
Tim: Online

???

Thank you for everything so far, I have been working on this for some time and you have help me so much.
0
 
SidFishesCommented:
The previous code did work except that it showed last activity and not Online (the code was missing one <br>)
 I've modified the code...drop this in and see what you get.

      <cfloop collection="#Application.UsersInfo#" item="uName">
            <cfif listlast(Uname) eq listLast(session.id)>
            <strong>#listlast(Uname)#</strong> is ME!<br>
            
            <cfelse>
            #listlast(Uname)# - Online!<br>
            </cfif>
      </cfloop>


0
 
overcolorAuthor Commented:
Thank you very much for taking the time to help me with this problem. I'm working on a big project and are always looking for someone to help me with problems. If you sometime out source your services please let me know your rate. I have other things that I would love to have someone work one. Mosty answering questions.
Dwayne
info@overcolor.com
0
All Courses

From novice to tech pro — start learning today.