اخوآني الكرآم,, تمكنت وبعد جهد جهيد بفضل الله من عمل السرفر يتصل بألكلينت باستعمال الإندي,,
وفي المرفقات الملفين الذي اعمل عليهما,,,
لكن اخوآني الكرآم,, هل ممكن احد يضع الكود المنآسب حتى اساطيع ان ارسل النصوص بين هذين البرنمجين,, كما سترون ففي الكلينت ميمو و اديت وكذلك في السرفر,,
الذي اود عمله هو كيف ارسل نص من الكلينت الى السرفر ؟؟؟ يعني اكتبه في الإديت ومن ثم اضغط على زر فيظهر في الميمو للسرفر,, وكذلك العكس, يعني ان ارسل من السرفر نص الى الميمو في الكلينت,,,
جزآكم الله خيرا وبارك الله لكم,,
سبحآن الله قد حآولت ولكن لم اجد شي يناسب لحد الآن,,
طبعا الذي اوده هو في الإندي 10 وليس 9 ,,,
استخدمت دلفي 2010 في هذا المشروع,,
والسلام عليكم ورحمة الله وبركآته
فرّج همّ المهمومين يا الله
اللهم فك قيد اسرانا و اسرى المسلمين
اخوآني الكرام,, ها قد بدئ الطريق بالنسبة لي مع الإندي ولكن هناك كثير من الحفر,, والله المستعان,,
تمكنت بفضل الله من احرآز تقدم وهو ارسآل النصوص من الكلينتس الى السرفر ,,, ولكن اخوآني الكرآم,,
لم اتمكن من عمل العكس,, فهل من توضيح بارك الله لكم عن كيفية ارسآل نص حتى يظهر لكل الكلينتس الذين هم متصلين في السيرفر,,, مثآل على التقدم الذي احرزته في المرفقآت,,
+ انه مثآل جيد جدا لكل مبتدئ ان يبدئ مع الإندي,,
بإتظآركم بارك الله لكم
صورة,, من برنآمجي الذي هو 3 في وآحد :laugh:
فرّج همّ المهمومين يا الله
اللهم فك قيد اسرانا و اسرى المسلمين
الحل الأول القديم
هو ببسطة وضع مكونات السرفر و الكلينت في كل من السرفر و الكلينت
تابع معي
بفرض S سرفر و c1 كلينت و c2 كلينت أخر
نضع في كل من S و c1 , c2 مكونين سرفر و كلينت و الارسال يتم بالشكل التالي
بالبداية كل الكلينت c1 , c2 يتصلون بالسرفر و يتم الارسل بشكل روتيني من عميل لخادم
و إذا اردنا ارسال من الخادم للعمليل يقوم الخادم S بالتصال بواسطة مكون العميل الذي لديه بمكون الخادم الموجود في العميل c1 و إذا اردنا لمجموعمن الاجهزة يعني S يريد ارسال ل c1 , c2 هنا نقوم بعمل حلقة تقوم بالاتصال بمكون الخادم الموجود بالعميل c1 ثم تقوم بقطع الاتصال معه و ثم تتصل بمكون الخادم الموجود بالعميل c2 و هكذا تتم العملية بشكل سليم تماما
نبدأ أولا بمشكلة العميل و هي كيف سيستقبل الأوامر من الخادم
الحل
هو ببساطة انشاء thread في الكلينت يقوم باستقبال الطلبات من السرفر سواء كانت عبارة عن String أو Stream و نضع به حدث Execute بالاضافة للكلاس المسؤول عن المزامنة و هذا هو الكود
PHP كود :
type TReadResponse= class(TThread) protected FConn: TIdTCPConnection; procedure Execute; override; public constructor Create(AConn: TIdTCPConnection); reintroduce;
end;
TWriteResponse = class(TIdSync) protected Atext: AnsiString; procedure DoSynchronize; override; public constructor Create(const AResponse: AnsiString); class procedure AddResponse(const AResponse: AnsiString);
end;
هذا هو الكود المسؤول عن بناء Thread
PHP كود :
constructor TReadResponse.Create(AConn: TIdTCPConnection); begin FConn := AConn; inherited Create(False); end;
و هذا الكود هو المسؤول عن استقبال الطلبات من السرفر
PHP كود :
procedure TReadResponse.Execute; begin while not Terminated and FConn.Connected do begin TWriteResponse.AddResponse(FConn.IOHandler.ReadLn('',enUTF8)); end; end;
و هذا الكود مسؤول عن عمل بناء كلاس المزامنة لاحظ أن الطلبات ستنتقل للسترنغ AText
class procedure TWriteResponse.AddResponse (const AResponse: AnsiString); begin with Create(AResponse) do try Synchronize; finally Free; end; end;
و بالنهاية ستجد أن الامر وصل إلى الاجراء DoSynchronize و فيه تستطيع وضع ما تشاء من أوامر مثل الاجراء onExecute في السرفر
و هذا جزء من الكود
PHP كود :
procedure TWriteResponse.DoSynchronize; begin ShowMessage(AText); end;
و هنا انتهينا من اعداد الكلاينت مع ملاحظة أنه بحال اردنا أن نستقبل Stream فالأمر يتم مباشرة من خلال مكون الكلاينت
PHP كود :
IdTCPClient1.IOHandler.ReadStream(MStream)
طبعا هنا نسأل انفسنا سؤال لماذا لم نقم بهذه العملية ببساطة من أجل استقبال السترنغ و الجواب ايضا ببساطة لأنه لا نعرف متى سيأتي الطلب من الخادم و لكن يمكننا مثلا من أجل استقبال الستريم بارسال رسالة من الخادم تعلم العميل بأن Stream سيأتي مثلا
PHP كود :
procedure TWriteResponse.DoSynchronize; var MStream : TMemoryStream ; begin if Atext = 'File is Comming' then begin MStream := TMemoryStream.Create; try Form1.IdTCPClient1.IOHandler.ReadStream(MStream) ; MStream.SaveToFile('c:\'); finally MStream.Free ; end; end; end;
طبعا يمكنك وضع مثلا Timer يقوم بالتحقق كل ثانية إذا كان هناك String قادم أو Stream و لكن Thread افضل بهذه الحالة
هكذا يكون انتهى قسم العميل و اصبح جاهزا لتلقي الأوامر من الخادم
ملحوظة
تجد أنني استخدم ال AnsiString و ال enUTF8 و ذلك ليتم نقل النصوص العربية بصورة صحيحة و بدون استفهامات؟؟؟؟؟؟؟؟؟
نقوم ببساطة بإنشاء Class هو من TIdServerContext نسميه مثلا TMyContext
و نضيف له Ip و نضيف له الاجراء SendingMsg
PHP كود :
type TMyContext = class(TIdServerContext) // Create Class To Send From Server To Client public IP: String; procedure SendingMsg(const IP: String; const AMsg: AnsiString); procedure SendFile(const IP : String ; cPath : AnsiString ; LFile : Ansistring) ; end;
و عندما نريد ارسال رسالة نبحث بقائمة الأيبيات الموجودة عن نفس الأي بي الذي نريد ارسال الرسالة له فإذا وجدناه ستتم ارسال الرسالة أليا
PHP كود :
procedure TMyContext.SendingMsg(const IP: String; const AMsg:AnsiString); //Send Message var List: TList; Context: TMyContext; I: Integer; begin List := form7.IdTCPServer1.Contexts.LockList; try for I := 0 to List.Count-1 do begin Context := TMyContext(List[I]); if Context.IP = IP then begin try Context.Connection.IOHandler.WriteLn(AMsg,enUTF8); except end; Exit; end; end; finally form7.IdTCPServer1.Contexts.UnlockList; end;
end;
و لكن لحظة عندما نضع هذا الكود لا يتم الارسال لماذا
لأنه ببساطة ال Contrxt الخاص بمكون السرفر غير Context الخاص بنا و الحل
نقوم بتحويل ال Context الخاص بالسرفر لل MyContext عند انشاء Form
PHP كود :
constructor TForm7.Create(AOwner: TComponent); // Convert Context For TCPServer To MyContext begin inherited Create(AOwner); IdTCPServer1.ContextClass := TMyContext; end;
و عندما يتصل أحد الأجهزة الكلاينت بالخادم الخاص بنا نقوم بإدخال معلوماته و خاصة IP ل MyContext
PHP كود :
procedure TForm7.IdTCPServer1Connect(AContext: TIdContext); // When Client Connect Do begin MyContext := AContext ; TMyContext(AContext).IP := TMyContext(AContext).Connection.Socket.Binding.PeerIP;
و الأن إذا اردنا ارسال رسالة ستصبح التعليمة بالشكل التالي(حيث IP هو أي بي الجهاز المراد أن نرسل له الرسالة)
طبعا هناك ملاحظة
إذا فرضنا أنك تريد ارسال طلب من الكلينت للخادم و استقبال النتيجة مباشرة فهنا لا داعي لكل هذه العملية
لأنه بعد اجرائية ارسال الطلب نضع مباشرة إجرائية استقبال و هذه هي الحال مثلا عندما يتصل الكلاينت يالخادم و يتحقق من أمر ما مثلا Password أو name أو غيره
يعني أن الكلاينت ينتظر الرد من السرفر مباشرة و إذا لم يأتي الرد خلال Timeout تتم عملية الفصل و لن ستقبل الكلاينت النتيجة
هنا طبعا الخادم سيرسل النتيجة مباشرة بعد استقبال الرسالة
و لكن إذا كان الأمر برنامج محادثة فهذا لا ينفع كما ذكرنا مسبقا
al-mob4rm3g كتب :بالنسبة للخيآر الأول اخي الكريم,, هل هو ينفع مع شآت كتآبي,, جمآعي؟
أنا طبقته لعمل شات من السرفر للكلينت و من الكلينت للسرفر و لكن لم أطوره ليصبح من الكلينت للكلينت بحيث يمر من خلال السرفر كما أنني لم أجرب برتوكولات أخرى مثل udp و التي على ما اعتقد تنفع بمثل هذه أمور
على كل حال أنا كنت ناوي أعمل برنامج شات جماعى و أنت شجعتني و إن شاء الله أباشر به غدا و نطوره سويا إذا أردت ذلك
o15s19 كتب :أنا طبقته لعمل شات من السرفر للكلينت و من الكلينت للسرفر و لكن لم أطوره ليصبح من الكلينت للكلينت بحيث يمر من خلال السرفر كما أنني لم أجرب برتوكولات أخرى مثل udp و التي على ما اعتقد تنفع بمثل هذه أمور
على كل حال أنا كنت ناوي أعمل برنامج شات جماعى و أنت شجعتني و إن شاء الله أباشر به غدا و نطوره سويا إذا أردت ذلك
أهلا بك أخي الكريم و رمضان مبارك
الله يبارك فيك اخي الكريم,, في الحقيقة فكرة رآئعة وانا سأكون اول المتآبعين لهذا البرنآمج,,
لو كنت استطيع المشآركة لما ترددت اخي الكريم,, لكن كما ترى,, فأنا لا اعرف شئ عن برمجة الكليت و السرفر وانا لا شئ يذكر امامك اخي الحبيب,, لكن ان كنت تريد عمل مثل هذا البرنآمج فسأكون اول من يحآول التعلم منه ان شاء الله,, + انني اشجعك كثيرا على هذا لآنني اود ان اتعلم هذا الشئ,, + انه لا يوجد كثير من المقآلات و الدروس عن الإندي 10, بالإضآفة الى الّغة العربية فهناك شبه سفر مقآلآت عن كيفية استخدآم الإندي 10,, لذلك اشجعك بقوة اخي الكريم,, :bye1:
حسنا,, ستبدئ غدا,, ؟ ان شاء الله
لا بئس,, على كل سأكون بإنتظآرك ان شاء الله ولا تنسى اخي الحبيب بعد اذنك ان تضع الخطوآت وآحدة تلوة الأخرى حتى افهم :oops:
الله يبارك فيك ويرفع قدرك في الدآرين, اللهم آمين,,
ان نويت ان تبدئ 100% اخبرني بارك الله لك ورفع قدرك وزآدك من علمه
والسلام عليكم ورحمة الله وبركآته
فرّج همّ المهمومين يا الله
اللهم فك قيد اسرانا و اسرى المسلمين