PDA

View Full Version : بررسی Online Users به صورت کاملاً حرفه ای در asp.net - رفع بعضی مشکلات - Webgozar چطوری عمل می کنه؟



majid_darab
پنج شنبه 18 خرداد 1391, 11:23 صبح
با سلام و ارادت
مدتی ست که دارم روی Online Users در ASP.NET با زبان برنامه نویسی C شارپ کار می کنم و بعضی نکات در این زمینه برایم آزار دهنده شده است.
خوب روش معمول برای Online Users استفاده از فایل global.asax می باشد که به صورت زیر انجام می شود:

void Application_Start(object sender, EventArgs e)
{
Application["OnlineUsers"] = 0;
}

void Session_Start(object sender, EventArgs e)
{
Application.Lock();
Application["OnlineUsers"] = (int)Application["OnlineUsers"] + 1;
Application.UnLock();
}

void Session_End(object sender, EventArgs e)
{
Application.Lock();
Application["OnlineUsers"] = (int)Application["OnlineUsers"] - 1;
Application.UnLock();
}


حال می توان این روش استفاده را گسترش داد و از دیتابیس برای ذخیره سازی Online Users استفاده کرد.
مثلاً به صورت زیر :

protected void Application_Start(object sender, EventArgs e)
{
Application["OnlineUsers"] = 0;

OnlineUsers.Update_SessionEnd_And_Online(
DateTime.Now,
false);
}

protected void Session_Start(object sender, EventArgs e)
{
Application.Lock();

//0:Session_Start
//Session_End
//1:Session_ID
//2:IP_Address
//3:Proxy_IPs
//4:UserAgent
//5:UserBrowser
//6:UrlReferrer
List<string> User_Info = GetUser_Info_IPAddress();

OnlineUsers.InsertRow(
DateTime.Parse(User_Info[0]),
DBNull.Value,
User_Info[1],
string.IsNullOrEmpty(User_Info[3]) ? false : true,
User_Info[2],
User_Info[3],
User_Info[4],
User_Info[5],
string.IsNullOrEmpty(User_Info[6]) ? DBNull.Value : (object)User_Info[6],
true);

Application["OnlineUsers"] = (int)Application["OnlineUsers"] + 1;
Application.UnLock();
}

protected void Session_End(object sender, EventArgs e)
{
Application.Lock();

OnlineUsers.UpdateRow_Some_Fields_By_SessionID(
DateTime.Now,
Session.SessionID,
false);

Application["OnlineUsers"] = (int)Application["OnlineUsers"] - 1;
Application.UnLock();
}


نکته ای که می خوام خدمتتون بگم اینه که در پروژه من از Membership خود دات نت استفاده نشده است و با Log In و Log Off کاری نداریم
تعریف من از آنلاین یوزرز این است که وقتی یک کاربر توسط بروزر خود، سایت منو باز می کنه یک واحد به آنلاین یوزرهای من افزوده بشه و وقتی می بنده درجا و بی وقفه یک واحد از آنلاین یوزرهای من کم بشه.
من برای اینکه بتونم تعداد بازدید رو مورد بررسی قرار دهم نیاز به دیتابیس دارم که Count گرفته شده در مورد افراد آنلاین از دیتابیس و Count گرفته شده از کالکشن Application باید یکی دربیاد که همیشه یکی دو تا با هم اختلاف دارن.حالا چرا باید از Session_End بپرسیم.
خوب حالا سوالات و مواردی که مشکل سازند:

1-آیا من برای ورود اطلاعات به دیتابیس به درستی از فاکتور Session.SessionID استفاده کرده ام؟
همان طور که در کدهای من می بینید من موقع Session_Start یک سری فاکتورها از جمله Session.SessionID را وارد دیتابیس می کنم و موقع Session_End توسط همین Session.SessionID کاربرو می ندازم بیرون
آیا استفاده از این فاکتور به این نحو درست است؟ یا باید از فاکتور دیگری استفاده می کردم؟

2-یکی از مشکلات این سیستم آنلاین یوزرز اینه که وقتی کاربر بروزرو می بنده مدت زمانی به اندازه Sesstion Timeout طول می کشه تا Session_End اجرا بشه و در این مدت من در سیستم خود کاربرو آنلاین می بینم.
در سیستم آمارگیری وب گذار این مشکل وجود ندارد!

3-مورد بعدی اینه که وقتی کاربر سایت منو در چند نوع بروزر مختلف رو باز می کنه چند Session مختلف براش ایجاد میشه و من چند کاربر در سیستم آنلاین یوزرز خودم ثبت می کنم که باز در سیستم آمارگیری وب گذار این مشکل وجود ندارد!

4-مشکل دیگری که سیستم من دارد در مورد تعداد بازدید می باشد که هنوز مفهوم دقیق آن برایم جا نیفتاده است.
اگر هر بار باز شدن وب سایت من توسط بروزر کلاینت را یک بازدید حساب کنیم پس سیستم من باز در این مورد به درستی عمل نمی کند.
چون سیستم من باز کردن تب های جدید در یک بروزر خاص را به دلیل دارا بودن Session یکسان محاسبه نمی کند که باز این مشکل در سیستم آمارگیری وب گذار وجود ندارد!

5-حالا بریم سراغ سیستم وب گذار و نگاه دقیق تری بهش بندازیم تا بتونیم معایب این سیستمی که با Session کار می کند رو رفع کنیم
فکر می کنم چاره تمامی مشکلات عنوان شده استفاده از برنامه نویسی سمت کلاینت باشد.
اما چطوری؟
همان طور که می دانید با وب متدها می شود از برنامه نویسی سمت کلاینت یک فانکشن سرورسایدو فراخوانی کرد و یا توسط Ajax موجود در jquey یک handler را فراخوانی کرد و کد های مربوط به آنلاین یوزرز رو پیاده سازی کرد.
در اینجا به نظرم مکانیزم نگه داری تعداد بازدید با اون چیزی که می خوایم جور در میاد
ولی مشکل اساسی ای که اینجا وجود دارد اینه که اگر سمت کلاینت از کدی مشابه زیر استفاده کنم :

<script type ="text/javascript" >
function CloseWindow()
{
alert("You are closing the window.Fire Session_End using EndSession.ashx");
}
window.onunload=CloseWindow;
</script>


و کاربر در بروزر خودش چند تب باز کرده باشه با بستن یکی از اونها Offline میشه.
نکته : پلاگینی در jquery وجود دارد به نام OnUserExit که بعضی از معایب کد جاوااسکریپت بالا رو حل می کنه، اما مشکل مطرح شده در مورد آن همچنان وجود دارد.
سیستم آمارگیری وب گذار چطور عمل می کند که چنین مشکلاتی در مورد آن وجود ندارد؟
این وب سایت هم با asp.net نوشته شده است و از زبان برنامه نویسی سمت کلاینت به خوبی بهره گرفته است.
نمونه کدی که وب گذار می دهد تا در میان کدهای HTML خود بزاریم به صورت زیره :



<div runat="server" id="webgozarCounter">
<script type="text/javascript" language="javascript" src="http://www.webgozar.ir/c.aspx?Code=25627&amp;t=counter"></script>
<noscript>
<a href="http://www.webgozar.com/counter/stats.aspx?code=25627" target="_blank">آمار</a></noscript>
</div>

خوب پس از فراخوانی اسکریپت بالا ما کدی مشابه کد زیر در وب سایتمون خواهیم داشت :


document.write('<script language="javascript" src="http://www.webgozar.ir/c.aspx?t=stats&code=25627&ref=' + escape(document.referrer) + '"></script>'); screensize=screen.width+'x'+screen.height;colors=( navigator.appName.indexOf('Microsoft')==0)?screen. colorDepth:screen.pixelDepth;if(colors=='undefined '){colors='5';};if(colors=='32'){colors='1';};if(c olors=='24'){colors='2';};if(colors=='16'){colors= '3';};if(colors=='8'){colors='4';};document.write ('<div align="center"><iframe scrolling=no width=125 height=110 border=0 frameborder=0 allowtransparency="true" src="http://engine.webgozar.com/counter/xstat.aspx?t=sum1&code=25627&rnd=' + Math.round(Math.random()*50000) + '&s=' + screensize + '&c=' + colors + '&ref=' + escape(document.referrer) + '&title=' + escape(document.title) + '" ></iframe></div>');

خوب تعداد بازدید با این سیستم جور در میاد که با هر بار باز شدن با Refresh شدن وب سایت ما، یک بازید به بازدید ها اضافه میشه.
اما کاربران آنلاین این سیستم چطوری عمل می کنه و از کجا می فهمه که یک کاربر چند تا تب باز کرده و یا وب سایتو در چند بروزر مختلف باز کرده؟
در عین حال از کجا می فهمه کاربر آفلاین شده - چون در میان این کدها کدی نیست که مشخص کنه مثلاً موقع بستن بروزر کار خاصی صورت بگیره.

اگر در مورد موارد بالا راهنمایی بفرمایید ممنون می شوم.
با تشکر از توجه شما