ورود

View Full Version : رويدادي در دلفي 7 هنگام Kill شدن Task؛ مثلا وقتي كه سيستم خاموش يا ريستارت ميشود!



diamond_guilan
یک شنبه 01 اردیبهشت 1392, 12:19 عصر
سلام و خسته نباشيد خمدمت دوستان محترم؛
ميخواهم حضور كاربران OnLine را در جدولي از بانك داشته باشم. وقتي كاربري Login ميكند، فيلد مربوطه true در غي اينصورت False شود.

مسئله اينجاست كه وقتي سيستم خاموش يا ريستارت شود چگونه بايد آن فيلد را False نمايم؟!

اگر راه حل ديگري نيز داريد پيشنهاد نمائيد.

::ممنون::

khorsandreza
یک شنبه 01 اردیبهشت 1392, 12:27 عصر
عملا نمیشه کنترل داشت ولی یک برنامه کوچکی نوشتم و دراخل سرور گذاشتم مرتب در زمان های خاص هر 5 دقیقه کاربران را وضعیت True دارند بر اساس IP کنترل میکند ببیند برنامه در حال اجراست یا نه اگر نه مقدار False می کند

diamond_guilan
یک شنبه 01 اردیبهشت 1392, 12:43 عصر
منم دقيقا تو بحث شبكه ميخوامش...
چون واسه ارسال پيام و بسته با IdTCPclient بايد حتما HOSTي كه بهش منتصب ميكنيم On باشه، در غير اينصورت پيغام خطا ميده كه با بلوك try هم حتما نميشه كنترل كرد و از دادن پيغام خطا جلوگير كرد!
راه حل؟!

یوسف زالی
یک شنبه 01 اردیبهشت 1392, 13:22 عصر
چرا سعی نمی کنید کامپوننت رو اصلاج کنید؟

BORHAN TEC
یک شنبه 01 اردیبهشت 1392, 13:23 عصر
سلام
بر طبق تجارب شخصی خودم فکر می کنم بهترین روش برای مدیریت چنین شرایطی بهره گیری از مکانیزم Session باشد. دلفی به طور پیش فرض فریم ورکی به نام DataSnap دارد که انجام این کارها در آن بسیار آسان است. به عنوان نمونه من مثالی که ضمیمه کرده ام را با استفاده از DataSnap در کمتر از 5 دقیقه(!) ایجاد کرده ام که فکر می کنم بتواند مشکل شما را حل نماید. این مثالی که قرار داده ام حتی قابلیت دیگری هم دارد و آن این است که اگر چند نمونه از برنامه کلاینت ما روی یک سیستم اجرا شده باشد باز هم اختلالی به وجود نمی آید و می توانید روی تک تک Instance ها هم کنترل داشته باشید. اگر برنامه را تست کنید این موضوع را بهتر متوجه خواهید شد. در ضمن من این کد را در نسخه XE3 ساخته ام. متاسفانه امروز به شبکه LAN دسترسی نداشتم که برنامه رو روی اون تست کنم و مجبور شدم که آنرا در vmware تست کنم که در این محیط به خوبی کار می کرد. در هر صورت بعید می دانم که برنامه مشکلی در شبکه واقعی داشته باشد. فقط خواهشمندم که اگر دوستی الان امکان تست داره سیستم کلاینت رو یکبار به صورت غیر معمول خاموش کنه، به عبارتی یکدفعه از برق بکشه (!) و ببینه که برنامه سرور متوجه این موضوع میشه یا نه. لطفاً اگر دوستی این مورد رو تست کرد در همین تاپیک گزارش کنه. :خجالت:

diamond_guilan
یک شنبه 01 اردیبهشت 1392, 14:12 عصر
متاسفانه من با دلفي 7 دارم كار ميكنم.
چرا تو بلوك try ميزارم باز همون error رو به كاربر ميده؟!!!!

BORHAN TEC
یک شنبه 01 اردیبهشت 1392, 14:16 عصر
چرا تو بلوك try ميزارم باز همون error رو به كاربر ميده؟!!!!
اگه منظورتون با من باشه باید بگم که توی DataSap استثناها معمولاً به صورت Remote هستند. این مورد رو چند روز قبل در تاپیک زیر توضیح دادم:
http://barnamenevis.org/showthread.php?393504

diamond_guilan
یک شنبه 01 اردیبهشت 1392, 14:36 عصر
ممنون از توجهتون، نه قربونتون برم حواسم نشد بقيه رو تايپ كنم و همونو فرستادم
من اين قضيه رو واسه ارسال پيام از طريق tcpserver و tcpclient ميخوام. تو اين روش هم واسه ارسال پيام از كلاينت به سرور، حتما سرور بايد On باشه ورگنه socketError ميده
اين دستورات رو تو بلوك Try ميزرام، اما باز error ميده!
چرا؟!

Mask
دوشنبه 02 اردیبهشت 1392, 09:18 صبح
چرا اینقدر بحثو پیچیده میکنید:
اینقدر ها هم که فکر میکنید سخت نیست .
در کامپوننت IdTcpServer ما رویدادی داریم به نام ONConnect و ONDisconnect.
از سمت کلاینت با استفاده از یه idTcpclient به سرور وصل بشید و حتما حواستون باشه که کانکشن رو disconnect نکنید. و بزارید باز باشه.
خوب الان کافیه تو رویداد ONConnect این کد رو بنویسید :

procedure TForm1.Button1Click(Sender: TObject);
begin
if IdTCPClient1.Connected then
IdTCPClient1.disConnect
else
IdTCPClient1.Connect;
end;

procedure TForm1.IdTCPServer1Connect(AContext: TIdContext);
begin
ListBox1.Items.Append(AContext.Binding.PeerIP);
end;

procedure TForm1.IdTCPServer1Disconnect(AContext: TIdContext);
begin
ListBox1.Items.Delete(ListBox1.Items.IndexOf(ACont ext.Binding.PeerIP));
end;

diamond_guilan
دوشنبه 02 اردیبهشت 1392, 12:04 عصر
جناب Gold؛ وقتي برنامه بدون اينكه از طرف كاربر بسته بشه؛ يعني به هر دليلي taskَش Kill بشه... كلانيت متوجه اين موضوع نميشه و از اونجايي هم كه بايد سرور حتما on باشه تا اين ارتباط صورت بگيره، پس Error ميده!

BORHAN TEC
دوشنبه 02 اردیبهشت 1392, 12:25 عصر
تنها راه حل باقی مانده در چنین شرایطی این است که هر چند ثانیه یکبار یک سیگنال کنترلی از سمت سرور به کلاینت ها فرستاده شود که کلاینتها باید به آن پاسخ دهند و اگر این کار را نکنند سرور متوجه می شود که اتصال برقرار نیست. البته قبل از این کار باید با کانکت شدن اولیه که از سمت کلاینت به سرور انجام میشود مشخصات کلاینت در لیست سیستم های متصل شده به سرور در برنامه سمت سرور اضافه شود. سرور این سیگنال کنترلی را باید به سیستم هایی که در این لیست قرار دارند ارسال کند. این سیگنال کنترلی به شکلهای مختلفی با استفاده از Indy و یا مکانیزم callback در DataSnap و ... قابل پیاده سازی است.

diamond_guilan
دوشنبه 02 اردیبهشت 1392, 12:36 عصر
با اجازتون من يكم برنامه اي رو كه نوشتم توضيح ميدم و ميگم هدف كلي م چيه:
هربار كه هر كاربري وارد سيستم ميشه، Ip سيستمش توي بانك Edit ميشه...
مدير واسه ارسال پيام به كلاينهتاش، توي بخش مربوط به اين كار، يه CheckListBox داره كه توش تمام كاربرا ليست شدند، چه اونايي كه connect هستن و چه اونايي كه نيستن...
وقتي چندتا رو انتخاب كرد تا بهشون پيام بده، اون كاربرايي كه Connect نيستن؛ برنامشون در حال اجرا نيست؛ وقتي به اونا ميرسه SoocketError ميده و از برنامه مياد بيرون، با اينكه اين دستورات رو توي بلوك Try گذاشتم امام باز Error رو ميده!!!

Mask
دوشنبه 02 اردیبهشت 1392, 12:55 عصر
جناب Gold؛ وقتي برنامه بدون اينكه از طرف كاربر بسته بشه؛ يعني به هر دليلي taskَش Kill بشه... كلانيت متوجه اين موضوع نميشه و از اونجايي هم كه بايد سرور حتما on باشه تا اين ارتباط صورت بگيره، پس Error ميده!
ربطی به کلاینت نداره. این پردازش ها در سرور انجام میگیره.
این صحبت شما نشون دهنده اینه که اصل صحبت منو درک نکردید.
برای تکمیل صحبتم : به هر دلیلی که کلاینت برنامه روش بسته بشه(چه kill بشه ، چه ریست و یا هر چی) رویداد ondisconnect سرور این موضوع رو میفهمه.

Delphi_Tips
دوشنبه 02 اردیبهشت 1392, 20:17 عصر
جناب Gold؛ وقتي برنامه بدون اينكه از طرف كاربر بسته بشه؛ يعني به هر دليلي taskَش Kill بشه... كلانيت متوجه اين موضوع نميشه و از اونجايي هم كه بايد سرور حتما on باشه تا اين ارتباط صورت بگيره، پس Error ميده!

شما اصلا قواعد TCP IP رو زير سوال بردين ! وقتي پروسس به هر نحوي بسته ميشه يا حتي كيل ميشه سيستم عامل يك سيگنال قطع ارتباط براي سرور يا كلاينت ارسال ميكنه كه شما فقط بايد در برنامتون رويداد مربوطه رو پردازش كنيد.

BORHAN TEC
دوشنبه 02 اردیبهشت 1392, 20:44 عصر
شما اصلا قواعد TCP IP رو زير سوال بردين ! وقتي پروسس به هر نحوي بسته ميشه يا حتي كيل ميشه سيستم عامل يك سيگنال قطع ارتباط براي سرور يا كلاينت ارسال ميكنه كه شما فقط بايد در برنامتون رويداد مربوطه رو پردازش كنيد.
موضوع سر اینه که اگه خود سیستم عامل به صورت غیر عادی از کار بیفته دیگه سیگنال قطع ارتباط فرستاده نمیشه که در این حالت تنها راه حل ممکن همونیه که توی پست 11 گفتم.

Delphi_Tips
دوشنبه 02 اردیبهشت 1392, 22:18 عصر
موضوع سر اینه که اگه خود سیستم عامل به صورت غیر عادی از کار بیفته دیگه سیگنال قطع ارتباط فرستاده نمیشه که در این حالت تنها راه حل ممکن همونیه که توی پست 11 گفتم.

بله راه حلي كه گفتيد يك راه حل اصولي و منطقيه كه توي خيلي از برنامه هاي بزرگ استفاده ميشه. منظورم بيشتر تاييد حرفي بود كه gold بهش اشاره كرد...

گرچه بحث اصلي هم بيشتر در مورد كيل شدن پروسس بود نه خاموشي ناگهاني سيستم

Mask
سه شنبه 03 اردیبهشت 1392, 10:17 صبح
گرچه بحث اصلي هم بيشتر در مورد كيل شدن پروسس بود نه خاموشي ناگهاني سيستم
در هر دو حالت کانکشن قط میشه و سرور از این رویداد با خبر میشه.
جسارتا :

هر چند ثانیه یکبار یک سیگنال کنترلی از سمت سرور به کلاینت ها فرستاده شود
وقتی خود سرور همچین امکانی رو به شما میده، این چه کاریه آخه.
کلیه ردیوس سرورها ، یا برنامه های اکانتینگی مثل Nttac یا ibs دقیقا با همین روش خروج کاربر و یا محدودیت تعداد لاگین رو میفهمند.

BORHAN TEC
سه شنبه 03 اردیبهشت 1392, 11:02 صبح
وقتی خود سرور همچین امکانی رو به شما میده، این چه کاریه آخه.
میشه بیشتر توضیح بدی؟

Mask
سه شنبه 03 اردیبهشت 1392, 11:30 صبح
میشه بیشتر توضیح بدی؟

پست شماره 9 رو بخون داداش.:قلب:

Delphi_Tips
سه شنبه 03 اردیبهشت 1392, 12:54 عصر
در هر دو حالت کانکشن قط میشه و سرور از این رویداد با خبر میشه.
این کجاش قواعد TCP IP زير سوال رفت.؟
.

اين جمله من خظاب به شما نبود. دقت و حوصله لطفا...