Users online

This forum is only for questions or discussions about working with the mojoPortal source code in Visual Studio, obtaining the source code from the repository, developing custom features, etc. If your question is not along these lines this is not the right forum. Please try to post your question in the appropriate forum.

Please do not post questions about design, CSS, or skinning here. Use the Help With Skins Forum for those questions.

This forum is for discussing mojoPortal development

This forum is only for questions or discussions about working with the mojoPortal source code in Visual Studio, obtaining the source code from the repository, developing custom features, etc. If your question is not along these lines this is not the right forum. Please try to post your question in the appropriate forum.

You can monitor commits to the repository from this page. We also recommend developers to subscribe to email notifications in the developer forum as occasionally important things are announced.

Before posting questions here you might want to review the developer documentation.

Do not post questions about design, CSS, or skinning here. Use the Help With Skins Forum for those questions.
This thread is closed to new posts. You must sign in to post in the forums.
10/29/2006 12:04:07 AM
Gravatar
Total Posts 68

Users online

Hi,

I want to show on a page who is online (in a specific role). Can I store this information in ApplicationState? Should I use Session_Start and Session_End in Global.asax to add/remove user ids to/from ApplicationState? I havn't figured out how to retreive the user id from the session that are being started/ended. Any ideas?

Thanks!

Christian

10/29/2006 2:25:26 AM
Gravatar
Total Posts 18439

Re: Users online

Hi Christian,

I'm planning to implement something like this soon but I hadn't really planned on making it role driven. I would like to do something  like DotNetNuke and have how many users online, newest user, new users today etc.

I generally never use session state for anything unless I absolutely have too and I don't think its needed here. In the membership api there is Membership.GetNumberOfUsersOnline() that counts based on last activity of the user and a window of time configurable in siteSettings.

My plan is to create a SiteStats class and cache it with say a 5 minute cache timeout (configurable from web.config). We can call this membership method to get the count but in order to keep it more up to date we may need to add a few more siteUser.UpdateLastActivityTime() statements in a few places. Like probably in Default.aspx.cs if the user is authenticated we can call this for every page view. We can also have a file cache dependency and invalidate the cache when a new user logs in or out.

Not sure if this will meet your needs since you are talking about specific roles but maybe it can be extended.

Joe
10/29/2006 3:18:09 AM
Gravatar
Total Posts 68

Re: Users online

Hi,

Thanks for your answer. I'm not really interested in how many that are online in this case but I want there id's so I can retreive the names of the users online (the roles arent that important here because I can filter that at a later point) Any ideas on how to solve this specific problem? Anything a I can use in Membership class?

Thanks!

Christian

10/29/2006 3:41:35 AM
Gravatar
Total Posts 18439

Re: Users online

I don't see anything in Membership for that. in mojoMembershipProvider the implementation is actually calling methods on SiteUser, this keeps it abstracted well so any db can be used so I would say we can add the needed method to SiteUser. Which db are you using? I can stub out a method for this on SiteUser and as soon as svn is back up I'll commit it or you can take this and implement it using similar logic to the count procedure then send me the changed files.

using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
 
public static Collection<SiteUser> GetUsersOnlineSince(int siteID, DateTime sinceTime)
{
    Collection<SiteUser> users = new Collection<SiteUser>();
 
    // TODO: code to populate collection goes here
   // retrieve a reader and populate new siteUser obejcts and add to collection
 
 
    return users;
}

We just need to get all the dbs implemented for the next release but we can start with the one you need.

Joe
10/29/2006 11:54:45 AM
Gravatar
Total Posts 68

Re: Users online

Hi Joe,

I'm using MySql, made it like this:

dbPortal:

public

{

 

sqlCommand.Append(

sqlCommand.Append(

 

arParams[0] =

arParams[0].Direction =

arParams[0].Value = SiteID;

arParams[1] =

arParams[1].Direction =

arParams[1].Value = sinceTime;

 

GetConnectionString(),

sqlCommand.ToString(),

arParams);

}

SiteUser:

public

{

 

 

 

 

{

users.Add(

}

 

}

static Collection<SiteUser> GetUsersOnlineSince(int siteID, DateTime sinceTime)Collection<SiteUser> users = new Collection<SiteUser>();IDataReader reader = dbPortal.SiteUser_GetOnlineSince(siteID, sinceTime);SiteSettings settings = SiteUtils.GetCurrentSiteSettings();while (reader.Read())new SiteUser(settings, Convert.ToInt32(reader["UserID"])));return users;

 

That should make it, right?

But there is stilll one issue that i'm thinking about, what would be a good since time for it to be accurate? You could set it to Now-CacheTime or something, but you can't know this way if the user has clicked the Logout button so its not 100 % accurate, right?

Christian

 

static IDataReader SiteUser_GetOnlineSince(int siteID, DateTime sinceTime)StringBuilder sqlCommand = new StringBuilder();"SELECT * FROM mp_Users WHERE SiteID = ?SiteID ");"AND LastActivityDate > ?SinceTime ; ");MySqlParameter[] arParams = new MySqlParameter[2];new MySqlParameter("?SiteID", MySqlDbType.Int32);ParameterDirection.Input;new MySqlParameter("?SinceTime", MySqlDbType.Datetime);ParameterDirection.Input;return MySqlHelper.ExecuteReader(
10/29/2006 11:57:29 AM
Gravatar
Total Posts 68

Re: Users online

Something got wrong with the copy-paste, trying again:

public static IDataReader SiteUser_GetOnlineSince(int siteID, DateTime sinceTime)

{

StringBuilder sqlCommand = new StringBuilder();

sqlCommand.Append("SELECT * FROM mp_Users WHERE SiteID = ?SiteID ");

sqlCommand.Append("AND LastActivityDate > ?SinceTime ; ");

MySqlParameter[] arParams = new MySqlParameter[2];

arParams[0] = new MySqlParameter("?SiteID", MySqlDbType.Int32);

arParams[0].Direction = ParameterDirection.Input;

arParams[0].Value = SiteID;

arParams[1] = new MySqlParameter("?SinceTime", MySqlDbType.Datetime);

arParams[1].Direction = ParameterDirection.Input;

arParams[1].Value = sinceTime;

return MySqlHelper.ExecuteReader(

GetConnectionString(),

sqlCommand.ToString(),

arParams);

}

 

{

Collection<SiteUser> users = new Collection<SiteUser>();

IDataReader reader = dbPortal.SiteUser_GetOnlineSince(siteID, sinceTime);

SiteSettings settings = SiteUtils.GetCurrentSiteSettings();

while (reader.Read())

{

users.Add(new SiteUser(settings, Convert.ToInt32(reader["UserID"])));

}

return users;

}

 

public static Collection<SiteUser> GetUsersOnlineSince(int siteID, DateTime sinceTime)
10/29/2006 12:14:38 PM
Gravatar
Total Posts 18439

Re: Users online

Hi Christian,

There is one thing, you don't want to do it like this:

while (reader.Read())new SiteUser(settings, Convert.ToInt32(reader["UserID"])));

because when you use that constructor for each user you are hitting the db again when you already have all the users data in the reader, this will exhaust the connection pool and cause performance problems.

it needs to be more like:

while(reader.Read())
{
SiteUser siteUser = new SiteUser();

siteUser.UserID = (int) reader["UserID"];
siteUser.Name = reader["Name"].ToString();
... populate the rest of the properties you need
users.Add(siteUser);

}

reader.Close();

as for the accuracy, yeah its just a judgement call, it can never be truly accurate in a stateless environment without really going against the grain. i'd probably go with 20-30 minutes.

You probably will want to add some code in Default.aspx.cs at the end of page load like this.

if(Context.User.IsAuthenticated)
{
SiteUser siteUser = SiteUtils.GetCurrentUser();
siteUser.UpdateLastActivityTime();
}

so the activity gets updated on every page view

Joe
10/29/2006 12:17:33 PM
Gravatar
Total Posts 18439

Re: Users online

Another option is instead of populating the collection like I previously suggested, you could just return the reader and bind to the reader, instead of creating all those user objects.

The more I think of it this is the most lightweight and more consistent with other things in mojoPortal. Generic collections are pretty cool but its extra overhead to create all those objects just for data binding, readers are much lighter.

Joe
10/29/2006 12:32:01 PM
Gravatar
Total Posts 68

Re: Users online

Yes, I only need the ids and the names so that would be a better idea. Thanks for your help and Im looking forward to see the SiteStatistics module.

Christian

You must sign in to post in the forums. This thread is closed to new posts.