PDA

View Full Version : عدم اجرای متد Session_End



ali_mnkt
پنج شنبه 06 آبان 1389, 20:18 عصر
با سلام

من نیاز دارم که کاربران online م رو نشون بدم. کد های زیر رو هم استفاده کردم :



در فایل Global.asax



protected void Application_Start(object sender, EventArgs e)
{

Application["OnlineUsers"] = 0;
}

protected void Session_Start(object sender, EventArgs e)
{


Application.Lock();

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

Application.UnLock();
}

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

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

Application.UnLock();
}و در web.Config :


<system.web>

<sessionState mode="InProc" cookieless="false" timeout="3" />
البته با توجه به این مقاله :

http://www.aspdotnetfaq.com/Faq/How-to-show-number-of-online-users-visitors-for-ASP-NET-website.aspx


یک virtual Directory ایجاد کردم و برنامه رو از طریق browser اجرا می کنم (مستقیما از طریق Vs اجرا نمی کنم ) . کاربران رو هنگامی که از طریق browser اجرا می کنم اضافه می کنه ولی وقتی که browser رو می بندم از کاربران online کم نمی کنه یعنی
Session_End رو اجرا نمی کنه . کسی می دونه مشگل کجاست ؟

adelisardo
پنج شنبه 06 آبان 1389, 21:38 عصر
دوست عزیز

توی همین مقاله هم توضیح داده که شما به اندازه مقدار timeout باید پس از بستن Browser صبر کنید تا متد Session_End اجرا بشه ،
آیا شما هر چقدر صبر می کنید اتفاقی تعداد کاربران ONLINE کم نمی شه ؟

با احترام

ali_mnkt
پنج شنبه 06 آبان 1389, 22:41 عصر
دوست عزیز

توی همین مقاله هم توضیح داده که شما به اندازه مقدار timeout باید پس از بستن Browser صبر کنید تا متد Session_End اجرا بشه ،
آیا شما هر چقدر صبر می کنید اتفاقی تعداد کاربران ONLINE کم نمی شه ؟

با احترام

با سلام خدمت شما . اگه دقت کرده باشید گفته شده اون TimeOut برای زمان انقضای session است و برای اینه که اگه کاربر برای یک مدت معین هیچ عکس العملی در صفحه از خودش نشون نداد session مربوط به اون حذف بشه. ولی باید قاعدتا با بستن browser متد Session_End از فایل Global اجرا بشه که نمی شه خوب پس این Session_End کی اجرا می شه ؟

adelisardo
پنج شنبه 06 آبان 1389, 23:46 عصر
با سلام خدمت شما . اگه دقت کرده باشید گفته شده اون TimeOut برای زمان انقضای session است و برای اینه که اگه کاربر برای یک مدت معین هیچ عکس العملی در صفحه از خودش نشون نداد session مربوط به اون حذف بشه. ولی باید قاعدتا با بستن browser متد Session_End از فایل Global اجرا بشه که نمی شه خوب پس این Session_End کی اجرا می شه ؟
صحبت شما کاملا درسته ولی این نکته رو نادیده گرفتید که زمانی که شما پنجره مرورگر رو می بندید فورا Session_End اتفاق نمی افتد .
بدلیل اینکه ما در یک محیط Connection Less کار می کنیم ( ارتباط بین کلاینت و سرور ) ، منظور اینه که سرور بر اساس درخواست کلاینت به آن پاسخ داده و ارتباط رو قطع می کنه و تا زمان درخواست بعدی ارتباطی در کار نیست .
این زمان Timeout می گه اگر بین دو درخواست کاربر بیش از این زمان وقفه افتاد Session کاربر از بین رفته و در صورت درخواست مجدد Session دیگری ساخته می شود و این تصور که در صورت بستن پنجره ، مرورگر درخواست حذف Session رو ارسال می کند نادرست است بنابراین اگر کاربری پنجره مرورگر خود را ببندد زمانی Session آن کاربر از بین می رود که به همان زمان ( Timeout ) از آخرین درخواست کاربر برسد .
در صورتی که نیاز دارید که در هنگام بسته شده پنجره Session از بین برود باید به طریقی ( خودتان کد بنویسید ) و متد ()Session.Abandon را اجرا کنید . این متد باعث از بین روفتن Session جاری می شود .
می توانید از سایت زیر همین اطلاعات رو مطالعه کنید :
http://www.vikramlakhotia.com/Mystries_of_when_does_Session_End_event_fires_in_A spNet.aspx

ali_mnkt
جمعه 07 آبان 1389, 00:56 صبح
دوست عزیز اگه اینجوری باشه که وضعیت خراب می شه :

فرض کن یک پنجره باز شده و در نتیجه یک نفر به لیست کاربران online اضافه شده خوب وقتی که session Timeout اون تموم شه متد session-End اجرا می شه حالا اینجا یه مشگلی وجود داره و اون هم این که اگه اون صفحه refresh بشه و یا با کلیک روی یک دکمه یک درخواست به سمت سرور بره چون session اون Expire شده متد Session-End فراخونی می شه و هی یکی از افراد online کم می شه !!!!! خوب چطور می شه از این جلوگیری کرد ؟

adelisardo
جمعه 07 آبان 1389, 10:37 صبح
دوست عزیز باز هم سلام
اولا که نرم افزار های و سیستم هایی که افراد Online رو نمایش می دهند به طور دقیق کار نمی کنند و این کار را با ضریبی از خطا نمایش می دهند .
درسته که اگر برای کاربری که مدتی با مرورگر خود با سایت شما کار نکند و از زمان TimeOut بگذرد Session آن کاربر از بین می رود ، ولی اگر کاربر دوباره درخواستی از همان مرورگر به سرور ارسال کند Session_Start فرخوانی می شود زیرا Session جدیدی برایش ساخته می شود .
نکته مهم اینه که زمان Expire ، بر اساس فاصله زمانی از آخرین درخواست سنجیده می شود IIS همیشه در حال بررسی فاصله زمانی آخرین درخواست یک Session است اگر این زمان از Timeout بیشتر شد Session به طور اتوماتیک از بین می رود و متد Session_End اجرا می شود ، هیچ ربطی هم به بستن مرورگر نداره ، شما اگر سایتی رو باز کنید ولی هیچ کاری توی اون سایت انجام ندید پس از رسیدن فاصله زمانی از آخرین درخواست شما به TimeOut ر Session ازبین می رود و متد Session_End اجرا میشه .
اگر من جای شما بودم و دقت کنترل تعداد افراد آنلاین واقعا برام مهم بود دو کار رو انجام می دادم :
- با استفاده از JavaScript در تمامی صفحات سایت یک AJAX METHOD را به مداوم با فاصله های زمانی مشخص ( کمتر از TimeOut ) اجرا می کردم و وضعیت کاربر رو به سرور گزارش می دادم .
- با استفاده از JavaScript کدی می نوشتم که زمانی که مرورگر بسته می شود دستور از بین رفتن Session رو به سرور ارسال کند ( AJAX Method ) .
البته این پیشنهادها نیاز به بررسی بیشتری داره ولی دقت شما را در شمارش آمار افراد آنلاین به شدت افزایش می دهد .
نکته مهم اینه که IIS هر نوع درخواستی رو درخواست حساب می کند حتی اجرا کردن متد های AJAX Method .
موفق باشید .