Link to home
Start Free TrialLog in
Avatar of jastroem
jastroem

asked on

Count users currently visiting a site

How can I get the number of users currently visiting a site (or page), and out put that number on a page?

If possible, it should work also if the users has turned off cookies in their browser.

Joergen Astroem

Avatar of cheekycj
cheekycj
Flag of United States of America image

I don't know of any "will work always" type solutions.

One method.. ugly but is.. having an Application.usercount var that gets incremented everytime someone visits the site.. (but set a session var.. to indicate you have already counted them)  But I don't know how you would decrement the counter on session expiration.

CJ
Avatar of tvanek
tvanek

I agree with CJ.

There's not really a way to determine this number due to the nature of HTTP.  Web applications are not like traditional applications - they are stateless.  This means that we don't have a TRUE way of tracking the "state" of the user the whole time that he/she is using the application.  We can only track state when a user makes a request (i.e. clicking a link, submitting a form).  In addition, any user can suddenly click "File - Open..." in the middle of your application and suddenly click over to www.ebay.com.  Your application can only determine that a user is gone by using timeouts.  If the user hasn't made a request in the last "x" number of minutes, consider that user as timed out.  However, sometimes that causes problems as well if the user hasn't really left.  Maybe the user was just on the phone for 40 minutes while staring at your web site idle in his web browser.

The short answer is as CJ said - there's no real reliable was to do this.

Probably not what you wanted to hear,

-Tyson
Tyson,
  Does CF allow you to execute code on Timeouts or during Session cleanup?

  I know some Java App servers -like during Garbage collection do but I am not sure about CF.

  Most sites that I have seen display user count have been in ASP.

CJ
As far as I know, CF does not.  The session timeout happens internally in CF's memory space - triggers no outside processes.  :-(

-Tyson
Well, the only other way to decrement the counter would be put JavaScript in to detect when someone clicks an external link or closes the browser and launch a cfm page that decrements the counter.. it would be messy and of course not ideal (because the onunload event in browsers is very quarky) but would provide a certain amount of info updating.

It seems as though you are out of luck when it comes to full solution.

I wonder if analyzing some web logs to get activity may work?

CJ
Well i think there was a similar question few days back.
the tag i proposed in that question also displays the no. of currently logged in users.

this is what tvanek had to say about that tag.but anyway i am giving that tag again
Just remember what I said in my previous post.

If you're going to use the custom tags that jimmy posted the link to, make SURE you are correctly using
<CFLOCK> tags.  Without them, marm my words - "You will repeatedly crash your ColdFusion Server(s)".

http://devex.allaire.com/developer/gallery/info.cfm?ID=CA3475A0-2830-11D4-AA9700508B94F380&method=Full

jimmy
ASKER CERTIFIED SOLUTION
Avatar of GunJack
GunJack

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Just a quick comment on this proposed answer.

I would hesitate to implement the solution that has been presented here.  No offense, GJ - it looks GREAT on paper.  However, consider the real-life effect of this.

If you're going to be continually reading/counting the sessions that are currently active, this requires using CFLOCKs in order to avoid crashing your server.  If you need more info on what I'm talking about, go read these articles on locking best practices, written by Ben Forta and Jim Schley:

http://www.allaire.com/handlers/index.cfm?id=17318&method=full
http://www.allaire.com/handlers/index.cfm?ID=17196&Method=Full

Without implementing the locking techniques mentioned in the above two articles, mark my words:

"You WILL crash your ColdFusion Server... again... and again... and again..."

Depending on your levels of traffic, these crashes could happen every two days or every two minutes.

Because all these SESSION reads are going to require locking, this could cause a HUGE performance bottleneck for your site - really depends on your levels of traffic and simultaneous activity.  CFLOCKs of the same SCOPE or the same NAME get queued and will only run when ColdFusion Server is not already processing code between a CFLOCK with the same SCOPE or NAME.  In the case of the proposed solution (and assuming you're running ColdFusion 4.5+), you would be using SCOPE=SESSION on your locks.

Again... looks great on paper... but I think you'll find that upon implementation of this solution, your server(s) is/are going to be BEGGING for mercy - assuming they don't kill themselves first.  :-)

No direct offense intended, GJ.

Hope this helps,

Tyson Vanek
Senior Consultant
< a l l a i r e > Corporation

P.S. - Jimmy282, glad to see that someone else has picked up my "CFLOCK" torch and is running with it.  I believe you directly quoted me.  :-)  If I had a dollar for every project I'd worked on where CFLOCKing was not being used and should have been... well... I'd be retired by now.
>a dollar

Hey I thought the proper quote used a dime :-)
Inflation huh ;-)

I must agree with Tyson on this.. the idea is looking good on paper but implementation wise.. It would be a huge performance hit.

You could just have a script read the server logs and count the # of unique IP addresses hitting the server in the last 5-15 mins and state that as the user count too.

CJ
IPs are not guaranteed to be unique, though.  In cases where people are coming through NAT or Firewalls/Proxys, many individual users can appear to be hitting your site simultaneously from the same IP.

> Hey I thought the proper quote used a dime :-)
> Inflation huh ;-)

You got it.  };->

Tyson Vanek
Senior Consultant
< a l l a i r e > Corporation
I agree with that.. and knowing that I still think it would give a fairly accurate count as any?  I mean all techniques are approximations right?

With inflation better bump it up to a few bucks :-)

CJ
I'm not sure I understand what your objection is.  If you feel that checking and setting a session variable on each page request is too resource intensive, why would anyone ever use them?  The majority of shopping cart systems use them and if they follow the locking techniques, they wouldn't be able to function according to your statements.

If you look at my solution, you'll see that you only need to create one session variable.  Since you only have to update it once every cycle, your locks don't have to be of the exclusive type except when you're doing the update to the session variable which doesn't necessarily occur on every request.  The exclusive lock would occur only once during the cycle time.

I have been coding in CF since version 2.0 and have been the administrator on a number of web systems including recently a server farm of 13 servers handling over a million hits a day across a dozen CF apps (stability was never an issue btw).  I have over 4 years of hands on real world CF experience so when I say you are grossly overestimating the resource issue, it's because I have the experience to back it up.  I have a system I wrote and maintain for a client which does about 4 million hits a month.  They spend over 200K a year advertising the site to drive the traffic in.  I coded it before reading the information on session locks so there are about a dozen session reads and writes on each page WITHOUT locking (the entire site is CF scritps).  I can count the number of times on one hand that the server has had problems this year and I think those have more to do with the build on the OS which I had no say over.   My point, please don't tell me how the server will crash repeatedly without them because it simply isn't true.  It is a risk but the chance of a collision is remote and doesn't even guarantee a crash.

No offense tyvanek but I just don't think you're statements are accurate based on what I've seen firsthand.

GJ
GJ,

Okay, first of all (as I mentioned a few times) this was not meant to be taken personally - obviously it was.  Apparently I have personally offended you by posting my opinion.

I'm not asking to see your "ColdFusion Expert" badge.  I'm not arguing your credentials or your experience.  I don't even know you, so how could I?  I will, however, say a few things in my "defense".  Quite simply, there are numerous reasons why I was hired by Allaire.  I have been working with ColdFusion since beta versions of 1.0.  Back in June of 1995, I was working with ColdFusion v0.97b - beta testing.  I've been working with ColdFusion for over 5 years.  I've presented classes at the Developer's Conference.  I've been the technical architect behind sites like footlocker.com - 750,000 hits a day, 2 8 server clusters, 2 RS6000 database servers.  I could go on and on and on... but I'm not here to brag - I'm here to help.

That said, let me throw in a few quotes from people who I work with at Allaire:

Jim Schley - Principal Tech Support Engineer
"Memory corruption also leads to crashes and/or server instability. Some of the symptoms of memory corruption follow:

- ColdFusion PCode errors
- cfserver process crashing/stopping/restarting
- Unexpected shared scope variable evaluation results
- Large growth in the amount of memory used by the cfserver process
- Operating system instability

Locking variables prevent these problems by only allowing one thread to access the shared scope variable at a time."

Ben Forta - ColdFusion Guru
In reference to a <CFSET SESSION.var = "foo"> without locking:
"If the <CFSET> statement above was executed at the exact same time as another <CFSET> statement that was updating the same variable, you'd likely corrupt server memory. If you're lucky, you'll just throw an error, but you could also negatively impact server operation as a whole."

Also...
"Locking is an important ColdFusion feature, and one that serious developers must use in their applications. Without locking there's a very real risk that data corruption will occur, and this can impact server stability.

Incorrect lock use, of course, can bring your application to its knees. That fine line must be walked. Yes, there are performance penalties involved, but every decision involves some kind of trade-off.

What you do is your choice. My advice? Lock it or lose it."

Perhaps, GJ, you have not yet directly seen any adverse effects due to lack of CFLOCKing your server-side variables.  Maybe you've seen them and you just don't recognize what the cause really is.  I'm not going to argue that.  However, I've been on over 50 consulting gigs where clients (like Victoria's Secret, Chicago Mercantile Exchange, Williams-Sonoma, Lockheed Martin, NetRadio) have had one RESOUNDING complaint - "ColdFusion Server keeps crashing and we don't know why!"

My first response to them 99% of the time is, "Well, are you locking your server-side variables?"  Their response 99% percent of the time is, "Uhhh.... what's locking?"  After correctly CFLOCKing all APPLICATION/SERVER/SESSION variable reads and writes, I have seen server stability increase 1000%... at least.

I'm not pulling stuff out of thin air here.  I've had discussions with Sim Simeonov (the godfather of ColdFusion, so to speak) and he has pointed this out to the consulting teams as the number one reason ColdFusion crashes on client sites.

If Joergen wants to implement your solution, he should go for it.  Like I said, it looks great on paper.  However, I'm just trying to make sure that he understands the risks involved with implementing that solution, both correctly and incorrectly.

GJ, if you'd like to argue further over the merits of CFLOCKing, I would encourage you to email me and perhaps I can eliminate any confusion - either by myself or with the help of other Allaire employees.  My email address is below.

Joergen, best of luck to you and whatever you decide to implement as a solution.

Regards,

Tyson Vanek
Senior Consultant
< a l l a i r e > Corporation
em: tvanek@allaire.com
Good to see we're not taking it personal.  I still don't understand your original complaint with the solution.  Your original comment basically said the solution wouldn't work in the real world because of the session locking required on the session variable.  Are you saying don't use session variables?
No, I'm not saying to not use session variables.  I also never said that your solution would not work.  I'm simply saying that if you are going to use session variables, you'll need to use locking.  And when you start using locking, you need to be careful.  Too many locks across too many simultaneous users can cause bottlenecks or the need for a "thicker" backend architecture - i.e. more servers into a cluster to split the load.

Myself?  No, I don't typically use session variables if I don't have to.  I usually will go with cookies if they are an option.  Nice thing about cookies is that then you do not have to worry about losing variables in clustered environments.  Sometimes, however, cookies are too limiting for my purposes (i.e. each cookie can only be 4k in size) and I will then use session variables - I'm just careful in how they are implemented.  Reads of session variables are not as costly as writes.  But if you start stacking too many session variables writes on top of eachother or start writing session variables too often, this requires exclusive locking of the session scope which will delay any other reads or writes to the session scope until the write is complete.

Another approach to this would be to create a centralized datasource for storing CLIENT variables and using them instead.  This approach enables all servers in the cluster to access variables in a common, shared back-end datasource.  This approach would eliminate the need for locking all together, but now introduces database overhead.

GJ, it's possible you have never experienced problems without coding CFLOCK tags because ColdFusion 4.5 introduced some new Administrator settings that can do some "auto" locking of the APPLICATION/SERVER/SESSION scopes.  With these auto setting enabled, you would not need to code your own CFLOCKs.  However, this method is a little more resource intense as ColdFusion has to do its own detection and locking of shared-scope variable activity.

Just to wrap up, I'm not saying your solution will not work.  I'm just trying to point out that there may be other costs associated with implementing it on a large scale.

Regards,

Tyson Vanek
Senior Consultant
< a l l a i r e > Corporation
This is the line from your first comment that I disagree with most and which seemed to summarize your opinion of the solution.

"Again... looks great on paper... but I think you'll find that upon implementation of this solution,
                     your server(s) is/are going to be BEGGING for mercy - assuming they don't kill themselves first.  :-)"

The solution I recommended required the use of one session variable to hold a simple date/time value and one shared application or server variable to hold an integer.  Your statement implies CF can't handle this as session and application variables will crash a server.

If you didn't really mean that, then I think the appropriate statement should have been "with this solution, just make sure you lock shared variables and make sure your server is sized for the load" or alternately  "to reduce the load on the server, use cookies instead of session variables and make sure you use locking around the global variable".
So be it.

With this solution, just make sure you lock shared variables and make sure your server is sized for the load.

To reduce the load on the server, use cookies instead of session variables and make sure you use locking around the global variables.
Avatar of jastroem

ASKER

Hi all of you

this question turned out to be a discussion that somehow goes beyond my knowledge of ColdFusion... anyhow I give the points to tvanek, not because it's the "best answer"... but I learned quite some from your comments.

Thanks to al of you & merry christmas
Joergen
uupss

GunJack got the points...

well - that's OK for me too!

Cheers
Joergen