View Full Version : حرفه ای: مشکل در شناخت عدم ااتصال در indytcpserver
sajioo
شنبه 26 مهر 1393, 16:41 عصر
دوستان سلام
بنده با راهنمایی های اساتید عزیز در این سایت موفق شدم یک مشکل مهم را برای برنامه ام حل کنم و آن اینکه وقتی یک کلاینت به سرور متصل است و به هر صورت دیسکانکت می شود با توجه به IdTCPServer1Disconnect می توان آن کلاینت را یافت و از لیست کاربران حذف کرد.
کاربر در برنامه من چه خروج بزند ، چه با task manager برنامه را ببندد این متد اجرا شده و سرور مطلع میشود که فلان کلاینت دیسکانکت شده است.
اما یک مشکل که خودم تست کردم و دیدم واقعا جواب نمیده.
اگر من به سرور متصل باشم و اینترنت کامپیوترم به هر نحوی قطع شود پروسجر IdTCPServer1Disconnect اجرا نمی شود و به زبان ساده تر سرور متوجه خروج کاربر نمی شود.
خودم چند بار اینترنت را قطع کردم و پس از وصل و مشاهده عملکرد سرور متوجه شدم سرور قطع این کلاینت را متوجه نشده است.
آیا راه حلی دیگر وجود دارد ؟ یا من دارم در جای خطایی انجام میدهم؟
دوستان لطفا راهنمایی بفرمایند:اشتباه:
sajioo
یک شنبه 27 مهر 1393, 11:29 صبح
دوستان کسی تا حالا این مشکل رو نداشته؟
یا یک راه حل ابتکاری میشه براش اوکی کرد؟
من خیلی گشتم تو نت اما چیزه خاصی نیافتم:عصبانی++:
Mask
دوشنبه 28 مهر 1393, 00:10 صبح
بهترین و سبکترین و منطقی ترین و عمومی ترین راه که همه برنامه ها حتی یاهو مسنجر استفاده میکنند استفده از Ping هست.
در فواصل زمانی کم کلاینتهارو پینگ کنید.
Felony
شنبه 03 آبان 1393, 06:07 صبح
کار نمیکنه چون شما ارتباط رو به صورت ناگهانی قطع کردید ، اون متد IdTCPServer1Disconnect هم فرضا اجرا شد ، وقتی اینترنت رو قطع کردید چطور به سرور اطلاع بده که اتصالش داره بسته میشه ؟
بهترین و سبکترین و منطقی ترین و عمومی ترین راه که همه برنامه ها حتی یاهو مسنجر استفاده میکنند استفده از Ping هست.
در فواصل زمانی کم کلاینتهارو پینگ کنید.
یعنی یاهو تمام چند ده میلیون کاربر Messenger شو هر چند دقیقه پینگ میکنه ؟! بعد مگه کلاینت هاش که کاربراش باشن IP استاتیک دارن که بتونه گیرشون بیاره و پینگشون کنه ؟! بعد مگه اکثرا پشت NAT نیستن ؟ چطوری پینگشون میکنه ؟!
راهکار کلی این هست که Messenger ها میان و یه سری سیگنال برای حالت های مختلف کاربر در نظر میگیرن که صرفا ارسال یک بایت به سرور از سمت کلاینت هست تا ترافیک خاصی رو به کلاینت و سرور تحمیل نکنه ، کلاینت ها وظیفه دارن وضعیت خودشون رو در هر شرایطی به سرور اعلام کنند ، این شرایط شامل Online, Busy, Idle, Offline و ... میتونه باشه ، یعنی حتی اگر کلاینت در حالت Idle به سر ببره وظیفه داره هر دقیقه وضعیتشو به سرور اعلام کنه ، حال اگر سرور برای چند دقیقه ( مثلا 10 دقیقه ) از سمت یک کلاینت وضعیتشو دریافت نکرد ، اون کلاینت رو به وضعیت آفلاین ثبت میکنه تا وقتی دوباره سیگنالی ازش دریافت بشه .
* سرور Domain ثابت داره که IP روش ست میشه تا راحت بتونن در زمان مورد نیاز بدون تغییر نرم افزار کلاینت ها سرور رو عوض کنن و فقط دامین رو روی یه IP دیگه ست کنن .
موفق باشید .
Mask
شنبه 03 آبان 1393, 14:03 عصر
یعنی یاهو تمام چند ده میلیون کاربر Messenger شو هر چند دقیقه پینگ میکنه ؟! بعد مگه کلاینت هاش که کاربراش باشن IP استاتیک دارن که بتونه گیرشون بیاره و پینگشون کنه ؟! بعد مگه اکثرا پشت NAT نیستن ؟ چطوری پینگشون میکنه ؟!
بیشتر پیاده سازی روش ملاک بود در اون پست . حالا سرور ، کلاینت رو پینگ بکنه یا برعکس، این رو برنامه و شرایط تعیین میکنه.
برای مسنجرها به علت مواردی که گفتید و هم اینکه ، کلاینت باید وضعیتش رو خودش بررسی کنه ، این عمل از کلاینت به سرور هست.
negative60
شنبه 17 آبان 1393, 20:13 عصر
در مورد ياهو مسنجر هردو اشتباه ميکنيد سرور ياهو برای تشخيص ديسکانت شدن غير طبيعی کلاينت با استفاده از توابع کتاب خونه سوکت اين کار رو انجام ميده نه کلاينت به سرور پکت ارسال ميکنه نه سرور به کلاينت.
راهکار کلی این هست که Messenger ها میان و یه سری سیگنال برای حالت های مختلف کاربر در نظر میگیرن که صرفا ارسال یک بایت به سرور از سمت کلاینت هست تا ترافیک خاصی رو به کلاینت و سرور تحمیل نکنه ، کلاینت ها وظیفه دارن وضعیت خودشون رو در هر شرایطی به سرور اعلام کنند ، این شرایط شامل Online, Busy, Idle, Offline و ... میتونه باشه ، یعنی حتی اگر کلاینت در حالت Idle به سر ببره وظیفه داره هر دقیقه وضعیتشو به سرور اعلام کنه ، حال اگر سرور برای چند دقیقه ( مثلا 10 دقیقه ) از سمت یک کلاینت وضعیتشو دریافت نکرد ، اون کلاینت رو به وضعیت آفلاین ثبت میکنه تا وقتی دوباره سیگنالی ازش دریافت بشه .
تو ياهو مسنجر ملاک آنلاين بودن کلاينت ارتباط دائمی هست که با اون برقرار کرده به اين شکل نيست که نياز باشه کلاينت هر چند دقيقه بگه من آنلايم! بلکه سوکت کلاينت از زمانی که به سرور ياهو لاگين ميشه باز ميمونه و بسته نميشه و اگر به هر دليلی ارتبات سوکت قطع بشه سرور اون کلاينت رو آفلاين حساب ميکنه.
دوستان سلام
بنده با راهنمایی های اساتید عزیز در این سایت موفق شدم یک مشکل مهم را برای برنامه ام حل کنم و آن اینکه وقتی یک کلاینت به سرور متصل است و به هر صورت دیسکانکت می شود با توجه به IdTCPServer1Disconnect می توان آن کلاینت را یافت و از لیست کاربران حذف کرد.
کاربر در برنامه من چه خروج بزند ، چه با task manager برنامه را ببندد این متد اجرا شده و سرور مطلع میشود که فلان کلاینت دیسکانکت شده است.
اما یک مشکل که خودم تست کردم و دیدم واقعا جواب نمیده.
اگر من به سرور متصل باشم و اینترنت کامپیوترم به هر نحوی قطع شود پروسجر IdTCPServer1Disconnect اجرا نمی شود و به زبان ساده تر سرور متوجه خروج کاربر نمی شود.
خودم چند بار اینترنت را قطع کردم و پس از وصل و مشاهده عملکرد سرور متوجه شدم سرور قطع این کلاینت را متوجه نشده است.
آیا راه حلی دیگر وجود دارد ؟ یا من دارم در جای خطایی انجام میدهم؟
دوستان لطفا راهنمایی بفرمایند
منم هم اين مشکل (http://barnamenevis.org/showthread.php?451885-%D8%AA%D8%B4%D8%AE%D9%8A%D8%B5-%D8%AE%D8%B1%D9%88%D8%AC-%D9%86%D8%A7%D9%85%D8%AA%D8%B9%D8%A7%D8%B1%D9%81-(%D8%B3%D9%88%DA%A9%D8%AA-%D9%BE%D8%B1%D9%88%DA%AF%D8%B1%D9%85%DB%8C%D9%86%D A%AF)&p=2021575&viewfull=1#post2021575) رو داشتم که حل شد
در سرور شما ميبايست با استفاده از هندل سوکت کلاينت KEEPALIVE هر کلاينت رو (اگر فعال نيست) فعال کنيد در اين صورت کتابخونه سوکت طی دوره زمانی مشخصی خودش زنده بودن ارتباط رو برسی ميکنه اما چون تو ويندوز زمان ديفالت KEEPALIVE خيلی زياده شما ميبايست با تابع WSAIoctl زمان SIO_KEEPALIVE_VALS رو مشخص کنيد
در اين صورت طی دوره زمانی کوتاه تری صحت اتصال انجام ميگيره و اگر کلاينتی به صورت غير معمولی ديسکانت شده باشه مشخص خواهد شد
Mask
شنبه 17 آبان 1393, 22:41 عصر
در مورد ياهو مسنجر هردو اشتباه ميکنيد سرور ياهو برای تشخيص ديسکانت شدن غير طبيعی کلاينت با استفاده از توابع کتاب خونه سوکت اين کار رو انجام ميده نه کلاينت به سرور پکت ارسال ميکنه نه سرور به کلاينت.
تو ياهو مسنجر ملاک آنلاين بودن کلاينت ارتباط دائمی هست که با اون برقرار کرده به اين شکل نيست که نياز باشه کلاينت هر چند دقيقه بگه من آنلايم! بلکه سوکت کلاينت از زمانی که به سرور ياهو لاگين ميشه باز ميمونه و بسته نميشه و اگر به هر دليلی ارتبات سوکت قطع بشه سرور اون کلاينت رو آفلاين حساب ميکنه.
منم هم اين مشکل (http://barnamenevis.org/showthread.php?451885-%D8%AA%D8%B4%D8%AE%D9%8A%D8%B5-%D8%AE%D8%B1%D9%88%D8%AC-%D9%86%D8%A7%D9%85%D8%AA%D8%B9%D8%A7%D8%B1%D9%81-(%D8%B3%D9%88%DA%A9%D8%AA-%D9%BE%D8%B1%D9%88%DA%AF%D8%B1%D9%85%DB%8C%D9%86%D A%AF)&p=2021575&viewfull=1#post2021575) رو داشتم که حل شد
در سرور شما ميبايست با استفاده از هندل سوکت کلاينت KEEPALIVE هر کلاينت رو (اگر فعال نيست) فعال کنيد در اين صورت کتابخونه سوکت طی دوره زمانی مشخصی خودش زنده بودن ارتباط رو برسی ميکنه اما چون تو ويندوز زمان ديفالت KEEPALIVE خيلی زياده شما ميبايست با تابع WSAIoctl زمان SIO_KEEPALIVE_VALS رو مشخص کنيد
در اين صورت طی دوره زمانی کوتاه تری صحت اتصال انجام ميگيره و اگر کلاينتی به صورت غير معمولی ديسکانت شده باشه مشخص خواهد شد
با وجود بسته قدرتمند Indy در دلفی ،از سوکت نویسی بیشتر در زبانهای برنامه نویسی مثل VB یا C++ استفاده میشود.
اگه قرار باشه اتصال از این روش بررسی بشه، کافیه در روال Disconnected سرور وضعیت کلاینتها بررسی بشه. البته من قبلا با کد این قضیه رو به طور کامل بررسی و شرح دادم. که گویا این دوستمون از این روش در شبکه محلی استفاده میکرده ، و مشکلی نداشته، اما در استفاده از این متد در شبکه اینترنت ، وضعیت دیسکانکت کلاینتها رو نتونسته تشخیص بده. که برای رفع این مشکل هم از طریق پینگ یا کد بایت تشخیص میتوان این مورد رو پوشش داد .
و هم اینکه (به قول شما ) KEEPALIVETime رو کم کنیم تا متد دیسکانکت سریعتر این قطعی رو هندل کنه.البته این مورد رو هم مد نظر داشته باشید، چون این مورد وابسته به سیستم عامل هست ، و با تغییر در API های موجود ، به کل ، وضعیت سیستم تغییر میکنه، در اینترنت ضعیف و پر قطعی ایران ، برنامه دچار یه وضعیت قطع و وصلی مداوم میشه. که البته برای این مورد میتونید، در هر سیستم یا در هر بار باز شدن برنامه شرایط و زمان رو تغییر بدید.
negative60
شنبه 17 آبان 1393, 23:25 عصر
با وجود بسته قدرتمند Indy در دلفی ،از سوکت نویسی بیشتر در زبانهای برنامه نویسی مثل VB یا C++ استفاده میشود.
خوب indy از چی استفاده ميکنه؟ از کتابخونه سوکت سيستم عامل ديگه! indy فقط يه کامپوننت که کار با سوکت و شبکه رو راحت کرده اما ميتونيد به هندل سوکت هم دسترسی داشته باشيد
اگه قرار باشه اتصال از این روش بررسی بشه، کافیه در روال Disconnected سرور وضعیت کلاینتها بررسی بشه. البته من قبلا با کد این قضیه رو به طور کامل بررسی و شرح دادم. که گویا این دوستمون از این روش در شبکه محلی استفاده میکرده ، و مشکلی نداشته، اما در استفاده از این متد در شبکه اینترنت ، وضعیت دیسکانکت کلاینتها رو نتونسته تشخیص بده. که برای رفع این مشکل هم از طریق پینگ یا کد بایت تشخیص میتوان این مورد رو پوشش داد .
اين دوستمون در مورد ديسکانت شدن غير معمول کلاينت صحبت ميکنه نميدونم تا بحال اين موضوع رو برسی کرديد يا نه ولی اگر pc کلاينت يکباره ريست يا خاموش بشه ، برق بره ، اينترنتش قطع بشه... در اين صورت در سرور رويداد Disconnected اتفاق نمييفته
farshad_shams
سه شنبه 20 آبان 1393, 09:56 صبح
بنده با راهنمایی های اساتید عزیز در این سایت موفق شدم یک مشکل مهم را برای برنامه ام حل کنم و آن اینکه وقتی یک کلاینت به سرور متصل است و به هر صورت دیسکانکت می شود با توجه به IdTCPServer1Disconnect می توان آن کلاینت را یافت و از لیست کاربران حذف کرد.
کاربر در برنامه من چه خروج بزند ، چه با task manager برنامه را ببندد این متد اجرا شده و سرور مطلع میشود که فلان کلاینت دیسکانکت شده است.
شما این مشکل در Indy رو چطور حل کردید؟
اگه امکانش هست قطعه کدی که برای
IdTCPServer1Disconnect نوشتید رو بذارید
vBulletin® v4.2.5, Copyright ©2000-1404, Jelsoft Enterprises Ltd.