View Full Version : سوال: مشکل در برنامه چت
Mask
پنج شنبه 29 مهر 1389, 12:56 عصر
برنامه زیر رو نگاه بفرمایید.
یه برنامه چت معمولیه.
مقداری رو که سیستم اول برا دوم میفرسته رو مجبورم با تایمر بریزم در ممو.
آیا eventi هست که به محض رسیدن به سیتم در ممو نمایش بده که مجبور نباشم از تامر استفاده کنم.
ممنون.
Felony
پنج شنبه 29 مهر 1389, 13:34 عصر
کلا اصول پیاده سازیتون مشکل داره ، برای برقراری یک ارتباط 2 طرفه بین کلاینت و سرور باید در هر دو طرف هم idTCP Client باشه و هم idTCP Server ، به این ترتیب در هر دو برنامه کلاینت و سرور میتونید ارتباط رو به صورت 2 طرفه پیاده کنید .
مهران رسا
پنج شنبه 29 مهر 1389, 13:36 عصر
یادمه قبلاً در این مورد بحث شده . شما میتونید از یک Thread جداگانه استفاده کنید تا همیشه برای دریافت پغام ها آماده باشه .
//By M8SPY
type
TListener = class(TThread)
protected
procedure Execute(); override;
private
public
var
Con: TIdTCPConnection;
RecMessages: integer;
Mess: string;
//
procedure Listen();
procedure DoX();
end;
implementation
{TListener}
procedure TListener.DoX;
begin
FrmMain.DataArrival(Mess);
end;
procedure TListener.Execute;
var
i: integer;
begin
inherited;
i := 0;
while i = 0 do
begin
sleep(10);
Listen;
end;
end;
procedure TListener.Listen;
begin
RecMessages := RecMessages + 1;
Mess := Con.IOHandler.ReadLn();
Synchronize(DoX);
end;
Felony
پنج شنبه 29 مهر 1389, 13:42 عصر
یادمه قبلاً در این مورد بحث شده . شما میتونید از یک Thread جداگانه استفاده کنید تا همیشه برای دریافت پغام ها آماده باشه .
//By M8SPY
type
TListener = class(TThread)
protected
procedure Execute(); override;
private
public
var
Con: TIdTCPConnection;
RecMessages: integer;
Mess: string;
//
procedure Listen();
procedure DoX();
end;
implementation
{TListener}
procedure TListener.DoX;
begin
FrmMain.DataArrival(Mess);
end;
procedure TListener.Execute;
var
i: integer;
begin
inherited;
i := 0;
while i = 0 do
begin
sleep(10);
Listen;
end;
end;
procedure TListener.Listen;
begin
RecMessages := RecMessages + 1;
Mess := Con.IOHandler.ReadLn();
Synchronize(DoX);
end;
این هم روشیه ولی از لحاظ فنی مورد قبول نیست ، دلیلی نداره برنامه برای تشخیص دریافت پیغام تو یه حلقه بیافته .
Felony
پنج شنبه 29 مهر 1389, 16:54 عصر
ممنون.
حاجی مجتبی میشه یه نمونه کامل که از نظر فنی سالم باشه رو برام بزاری؟
ممنون.
یه نمونه برنامه نوشتم ، بسته به نیازتون تغییرش بدید .
مهران رسا
پنج شنبه 29 مهر 1389, 18:10 عصر
یه نمونه برنامه نوشتم ، بسته به نیازتون تغییرش بدید .
روش شما peer to peer هست نه Client/Server . در یک برنامه تحت شبکه زمانیکه کلاینتی به سرور متصل شد دیگه دلیلی نداره سرور برای ارسال پیغام ، مجدداً به کلاینت ها متصل بشه چراکه این پل ارتباطی قبلاً ایجاد شده . حالا از اونجایی که در سمت کلاینت (استفاده از کنترل TcpClient) رویدادی برای دریافت پیغام ها ارسال شده توسط سرور وجود نداره ناچاریم راه حلی ارائه کنیم تا از طریق اون ، کلاینت ، همیشه در حال بررسی IOHandler بوده و در صورت دریافت پیغام جدید اون رو نمایش بده .
Felony
پنج شنبه 29 مهر 1389, 18:23 عصر
روش شما peer to peer هست نه Client/Server . در یک برنامه تحت شبکه زمانیکه کلاینتی به سرور متصل شد دیگه دلیلی نداره سرور برای ارسال پیغام ، مجدداً به کلاینت ها متصل بشه چراکه این پل ارتباطی قبلاً ایجاد شده . حالا از اونجایی که در سمت کلاینت (استفاده از کنترل TcpClient) رویدادی برای دریافت پیغام ها ارسال شده توسط سرور وجود نداره ناچاریم راه حلی ارائه کنیم تا از طریق اون ، کلاینت ، همیشه در حال بررسی IOHandler بوده و در صورت دریافت پیغام جدید اون رو نمایش بده .
الان بحث روش نیست ، بحث نحوه پیاده سازی بهتر و فنی تر این موضوع هست ، داشتم توضیحات مینوشتم که یادم افتاد قبلا خودت در مورد Indy سوالاتی کرده بودی و آقای کشاورز بهش پاسخ داده بود ، گشتم و پیداش کردم : http://barnamenevis.org/forum/showthread.php?t=219300
پست شماره 6 آقای کشاورز رو بخون .
مهران رسا
پنج شنبه 29 مهر 1389, 19:44 عصر
اشغال دو port برای ایجاد ارتباطات این چنینی به همون اندازه اشتباه هست که از Timer برای دریافت پیغام ها استفاده کنیم .
وقتی از طریق پورت x یکبار ارتباطی شکل گرفته چه دلیلی داره مجدداً یک خط ارتباطی جدید ایجاد کنیم ؟
اما اگر سرور شما برای خودش، بدون اینکه درخواستی از کلاینت دریافت کرده باشه، پیامی برای کلاینت بفرسته، اون وقت دیگه جای سرور و کلاینت عوض شده؛
از نظر من این تعریف برای یک برنامه Messenger صحیح نیست . در یک Messenger سرور همیشه سروره . اینجا منظور از سرور کامپیوتری مرکزی هست که تمامی پیغام های رد و بدل شده بین کاربران باید اول از اونجا بگذره . وقتی در شبکه یک عدد از این کامپیوتر بیشتر نباشه دیگه کاری نداریم چه کامپیوتری ماهیت سرور داره و چه کامپیوتری ماهیت کلاینت داره و اون کامپیوتر مرکزی رو سرور مینامیم .
در یک سیستم کلاینت/سرور معمولاً "سرور" Listen هست و تدابیر امنیتی مثل نصب فایروال و ... هم فقط روی سرور انجام میشه و مجوز بازکردن پورت جدید هم فقط از طریق سرور از سیستم عامل گرفته میشه . به عنوان مثال برنامه Yahoo Messenger رو تصور کنید . آیا در زمان اجرای این برنامه کادر معروف مربوط به فایروال برای دریافت مجوز باز کردن پورت جدید باز میشه ؟ خیر !در حالیکه وقتی توسط کنترل TcpServer برای بازکردن و Listen شدن به یک پورت جدید اقدام میکنیم ویندوز از شما مجوز دریافت میکنه .
البته میشه بدون استفاده از دو کامپوننت هم برای IdTCPClient پیام ارسال کرد، و با استفاده از همون Timer یا حلقه، آمدن پیام را بررسی کرد، ولی بهتره از دو کامپوننت استفاده کنید.
ما قبلاً در این مورد بارها با آقای کشاورز بحث کردیم . ایشون نگفتند استفاده از Thread برای پیاده سازی این روش اشتباهه . اما قبول دارم که استفاده از حلقه در Thread هم از نظر فنی صحیحی نیست . که برای حل این مشکل هم آقای کشاورز استفاده از روش هایی مثل ایجاد event رو پیشنهاد کردند .
Felony
پنج شنبه 29 مهر 1389, 20:09 عصر
از نظر من این تعریف برای یک برنامه Messenger صحیح نیست . در یک Messenger سرور همیشه سروره . اینجا منظور از سرور کامپیوتری مرکزی هست که تمامی پیغام های رد و بدل شده بین کاربران باید اول از اونجا بگذره . وقتی در شبکه یک عدد از این کامپیوتر بیشتر نباشه دیگه کاری نداریم چه کامپیوتری ماهیت سرور داره و چه کامپیوتری ماهیت کلاینت داره و اون کامپیوتر مرکزی رو سرور مینامیم .
اتفاقا تعریف درست و به جایی هست ، سرور وظیفش پاسخگویی به یک درخواست هست نه درخواست دادن !
در یک سیستم کلاینت/سرور معمولاً "سرور" Listen هست و تدابیر امنیتی مثل نصب فایروال و ... هم فقط روی سرور انجام میشه و مجوز بازکردن پورت جدید هم فقط از طریق سرور از سیستم عامل گرفته میشه . به عنوان مثال برنامه Yahoo Messenger رو تصور کنید . آیا در زمان اجرای این برنامه کادر معروف مربوط به فایروال برای دریافت مجوز باز کردن پورت جدید باز میشه ؟ خیر !در حالیکه وقتی توسط کنترل TcpServer برای بازکردن و Listen شدن به یک پورت جدید اقدام میکنیم ویندوز از شما مجوز دریافت میکنه .
پیاده سازی اون سرور زمین تا آسمون با سرور Local فرق میکنه ! ، خودت جواب خودت رو دادی ، سرور یک Listener هست و وظیفش گوش کردن به درخواست ها ، حالا چون Firewall برای باز کردن پورت بهش گیر میده دلیل به تفاوت ماهیتش نمیشه .
ما قبلاً در این مورد بارها با آقای کشاورز بحث کردیم . ایشون نگفتند استفاده از Thread برای پیاده سازی این روش اشتباهه . اما قبول دارم که استفاده از حلقه در Thread هم از نظر فنی صحیحی نیست . که برای حل این مشکل هم آقای کشاورز استفاده از روش هایی مثل ایجاد event رو پیشنهاد کردند .
من هم نگفتم اشتباهه ولی وقتی این همه پورت آزاد روی سیستم هست دلیلی به این بند و بسات ها نمیبینم و با وجود این همه پورت آزاد استفاده از تایمر به نظرم غیر فنی تر به حساب میاد !
مهران رسا
پنج شنبه 29 مهر 1389, 20:19 عصر
وقتی این همه پورت آزاد روی سیستم هست دلیلی به این بند و بسات ها نمیبینم
منطقی به نظر نمیرسه ...
راستش دیگه حوصله ندارم توضیح بدم . شما اگه یکبار با روشهای Non-Blocking کار کرده باشی متوجه منظورم میشی.
Mask
جمعه 30 مهر 1389, 00:02 صبح
آقا مجتبی ممنون.
من این کد رو در دلفی 7 میخام کامپایل کنم و به یه سری از پروپرتی های کامپوننتها که گیر میده هیچ... چنتا گیره خفن تر هم میده ...
نگا
IOHandler.WriteLn(ED_Message.Text);
AContext.Connection
procedure IdTCPServer1Execute(AContext: TIdContext);
اگه برات مقدوره یه نگا با دلفی 7 بنداز.
ممنون.
دمت گرم/
Felony
جمعه 30 مهر 1389, 05:59 صبح
آقا مجتبی ممنون.
من این کد رو در دلفی 7 میخام کامپایل کنم و به یه سری از پروپرتی های کامپوننتها که گیر میده هیچ... چنتا گیره خفن تر هم میده ...
نگا
اگه برات مقدوره یه نگا با دلفی 7 بنداز.
ممنون.
دمت گرم/
چیز خاصی نیست ، به خاطر تفاوت ورژن Indy هست ، چند دقیقه وقت میزاشتید درستش میکردید .
K.Mohammadreza
جمعه 30 مهر 1389, 16:05 عصر
با سلام اصولا نوشتن برنامه چت بصورت Client و Server کار چنداني نداره و نيازي نيست تاپيک اضافي در سايت درست بشه و ما هم بشينيم و چند صفحه در مورد اون توضيح و مثال بزنيم. اينترنت معدن اينگونه برنامه هاست که اکثراً هم اپن سورس هستند و نمونه زير هم يکشونه
که حتي آفلاين و آنلاين بودن را هم تشخيص ميده
vBulletin® v4.2.5, Copyright ©2000-1404, Jelsoft Enterprises Ltd.