ارسآل النصوص بين الكلينت و السرفر مع الإندي, ؟
#1
السلام عليكم ورحمة الله

اخوآني الكرآم,, تمكنت وبعد جهد جهيد بفضل الله من عمل السرفر يتصل بألكلينت باستعمال الإندي,,

وفي المرفقات الملفين الذي اعمل عليهما,,,

لكن اخوآني الكرآم,, هل ممكن احد يضع الكود المنآسب حتى اساطيع ان ارسل النصوص بين هذين البرنمجين,, كما سترون ففي الكلينت ميمو و اديت وكذلك في السرفر,,

الذي اود عمله هو كيف ارسل نص من الكلينت الى السرفر ؟؟؟ يعني اكتبه في الإديت ومن ثم اضغط على زر فيظهر في الميمو للسرفر,, وكذلك العكس, يعني ان ارسل من السرفر نص الى الميمو في الكلينت,,,

جزآكم الله خيرا وبارك الله لكم,,
سبحآن الله قد حآولت ولكن لم اجد شي يناسب لحد الآن,,

طبعا الذي اوده هو في الإندي 10 وليس 9 ,,,
استخدمت دلفي 2010 في هذا المشروع,,

والسلام عليكم ورحمة الله وبركآته


الملفات المرفقة
.rar   indy.rar (الحجم : 19.7 ك ب / التحميلات : 64)
فرّج همّ المهمومين يا الله
اللهم فك قيد اسرانا و اسرى المسلمين
الرد
#2
بسم الله,,

اخوآني الكرام,, ها قد بدئ الطريق بالنسبة لي مع الإندي ولكن هناك كثير من الحفر,, والله المستعان,,

تمكنت بفضل الله من احرآز تقدم وهو ارسآل النصوص من الكلينتس الى السرفر ,,, ولكن اخوآني الكرآم,,

لم اتمكن من عمل العكس,, فهل من توضيح بارك الله لكم عن كيفية ارسآل نص حتى يظهر لكل الكلينتس الذين هم متصلين في السيرفر,,, مثآل على التقدم الذي احرزته في المرفقآت,,

+ انه مثآل جيد جدا لكل مبتدئ ان يبدئ مع الإندي,,

بإتظآركم بارك الله لكم

صورة,, من برنآمجي الذي هو 3 في وآحد :laugh:

[صورة: i3x9h4.jpg]


الملفات المرفقة
.rar   Client_server_in_same_apps.rar (الحجم : 478.35 ك ب / التحميلات : 116)
فرّج همّ المهمومين يا الله
اللهم فك قيد اسرانا و اسرى المسلمين
الرد
#3
طيب اخوآني الكرام,, يبدوا اننا نفتقد خبير Indy في المنتدى,, :cryss: ربما اصبح انا في المستقبل ان شاء الله,,

على كل حال لن استسلم مهما كانت هذه العمليّة صعبة,, :laugh:

اخوآني الكرام,,

آمر يحيّرني مع هذه المكونات وهو,,

الذي فهمته من التعآمل مع الإندي فإنه يفتح اتصآل مع الخآدم ,, وبعدها يرسل او يستقبل البيانات ومن ثم يغلق الإتصآل,, هل فهمي للتعآمل مع الإندي صحيح ؟

طيب,, ان كان كذلك,,
كيف ممكن ان ارسل نص من الخآدم الى كل العملآء المتصلين معي في الخآدم ان كان العملآء اصلا يغلقون الإتصآل بعد فتحه,,

ان شاء الله السؤآل وآضح ؟

بارك الله لكم وجزآكم خيرا والسلام عليكم ورحمة الله
فرّج همّ المهمومين يا الله
اللهم فك قيد اسرانا و اسرى المسلمين
الرد
#4
السلام عليكم

بالنسبة لهذه الحالة لديك حلين حسب معرفتي

الحل الأول القديم
هو ببسطة وضع مكونات السرفر و الكلينت في كل من السرفر و الكلينت
تابع معي
بفرض S سرفر و c1 كلينت و c2 كلينت أخر
نضع في كل من S و c1 , c2 مكونين سرفر و كلينت و الارسال يتم بالشكل التالي
بالبداية كل الكلينت c1 , c2 يتصلون بالسرفر و يتم الارسل بشكل روتيني من عميل لخادم
و إذا اردنا ارسال من الخادم للعمليل يقوم الخادم S بالتصال بواسطة مكون العميل الذي لديه بمكون الخادم الموجود في العميل c1 و إذا اردنا لمجموعمن الاجهزة يعني S يريد ارسال ل c1 , c2 هنا نقوم بعمل حلقة تقوم بالاتصال بمكون الخادم الموجود بالعميل c1 ثم تقوم بقطع الاتصال معه و ثم تتصل بمكون الخادم الموجود بالعميل c2 و هكذا تتم العملية بشكل سليم تماما
الرد
#5
الحل الثاني الجديد المتطور

نبدأ أولا بمشكلة العميل و هي كيف سيستقبل الأوامر من الخادم
الحل

هو ببساطة انشاء 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

PHP كود :
constructor TWriteResponse.Create(const AResponse: AnsiString);
begin
 AText 
:= AResponse;
 
inherited Create;
end; 

و هذا الكود مسؤول عن بدء عملية المزامنة

PHP كود :
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 و ذلك ليتم نقل النصوص العربية بصورة صحيحة و بدون استفهامات؟؟؟؟؟؟؟؟؟
الرد
#6
و الأن كيق سيرسل الخادم رسالة للعميل
الحل

نقوم ببساطة بإنشاء 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 هو أي بي الجهاز المراد أن نرسل له الرسالة)
PHP كود :
TMyContext(Form7.MyContext).SendingMsg(IP,'Hello'); 

و هكذا ستتم العملية بنجاح إن شاء الله

و أهلا بك أخي الكريم
الرد
#7
طبعا هناك ملاحظة
إذا فرضنا أنك تريد ارسال طلب من الكلينت للخادم و استقبال النتيجة مباشرة فهنا لا داعي لكل هذه العملية
لأنه بعد اجرائية ارسال الطلب نضع مباشرة إجرائية استقبال و هذه هي الحال مثلا عندما يتصل الكلاينت يالخادم و يتحقق من أمر ما مثلا Password أو name أو غيره
يعني أن الكلاينت ينتظر الرد من السرفر مباشرة و إذا لم يأتي الرد خلال Timeout تتم عملية الفصل و لن ستقبل الكلاينت النتيجة
هنا طبعا الخادم سيرسل النتيجة مباشرة بعد استقبال الرسالة
و لكن إذا كان الأمر برنامج محادثة فهذا لا ينفع كما ذكرنا مسبقا

و السلام عليكم و رمضان مبارك
الرد
#8
بارك الله لك اخي الكريم بمشآركتك وجزآك الله كل خير,, وبآرك فيك وعليك وزآدك من فضله الله آمين,,

الخي الكريم,, اسعدتني كثيرا بمشآركتك,, وان شاء الله سأحآول تطبيقها,,

بالنسبة للخيآر الأول اخي الكريم,, هل هو ينفع مع شآت كتآبي,, جمآعي؟

و الخيآر الثآني يبدوا اننه مخصص للمحترفين :unsure: لكن سأحآول ان شاء تعلى,,

وآكثر ما اعجبني اخي الكريم,, هي جملتك,,

إقتباس :ملحوظة
تجد أنني استخدم ال AnsiString و ال enUTF8 و ذلك ليتم نقل النصوص العربية بصورة صحيحة و بدون استفهامات؟؟؟؟؟؟؟؟؟

هذه احجبتني كثيرا,, ويكفي هذه حتى ابذل جهدا للوصول الى الهدف ان شاء الله تعلى,, + انني كنت ابحث عن هذا,, فجزآك ربي خير الجزآء,,

----------

صرآحة اخوآني الكرآم كنت اتصور ان برمجة الشبكآت او شآت جمآعي اسهل من هذا ,,

تصوري لما كان سيحدث هو التآلي,,

اولاً,, هناك السرفر او الخآدم,,

يكون على جهآز,,

يتصل الكلينت او العميل بالخآدم,, ثم يتصل مثلا كلينت آخر بالخآدم حتى يصبح هناك مثلا 10 من العملآء منصلون بالخآدم,,

بعد ذلك يكتب احد العملآء نص,, فيرسل الى الخآدم وبعدها يقوم الخآدم بنشر النص الى بآقي العملآء,,

وتندهي المشكلة وكل شئ تمام وسهل و يسير,,

على كل حال,, خيرا ان شاء الله تعالى,,

بارك الله لكم,, والسلام عليكم ورحمة الله وبركآته,,
فرّج همّ المهمومين يا الله
اللهم فك قيد اسرانا و اسرى المسلمين
الرد
#9
al-mob4rm3g كتب :بالنسبة للخيآر الأول اخي الكريم,, هل هو ينفع مع شآت كتآبي,, جمآعي؟

أنا طبقته لعمل شات من السرفر للكلينت و من الكلينت للسرفر و لكن لم أطوره ليصبح من الكلينت للكلينت بحيث يمر من خلال السرفر كما أنني لم أجرب برتوكولات أخرى مثل udp و التي على ما اعتقد تنفع بمثل هذه أمور
على كل حال أنا كنت ناوي أعمل برنامج شات جماعى و أنت شجعتني و إن شاء الله أباشر به غدا و نطوره سويا إذا أردت ذلك

أهلا بك أخي الكريم و رمضان مبارك
الرد
#10
o15s19 كتب :أنا طبقته لعمل شات من السرفر للكلينت و من الكلينت للسرفر و لكن لم أطوره ليصبح من الكلينت للكلينت بحيث يمر من خلال السرفر كما أنني لم أجرب برتوكولات أخرى مثل udp و التي على ما اعتقد تنفع بمثل هذه أمور
على كل حال أنا كنت ناوي أعمل برنامج شات جماعى و أنت شجعتني و إن شاء الله أباشر به غدا و نطوره سويا إذا أردت ذلك

أهلا بك أخي الكريم و رمضان مبارك

الله يبارك فيك اخي الكريم,, في الحقيقة فكرة رآئعة وانا سأكون اول المتآبعين لهذا البرنآمج,,

لو كنت استطيع المشآركة لما ترددت اخي الكريم,, لكن كما ترى,, فأنا لا اعرف شئ عن برمجة الكليت و السرفر وانا لا شئ يذكر امامك اخي الحبيب,, لكن ان كنت تريد عمل مثل هذا البرنآمج فسأكون اول من يحآول التعلم منه ان شاء الله,, + انني اشجعك كثيرا على هذا لآنني اود ان اتعلم هذا الشئ,, + انه لا يوجد كثير من المقآلات و الدروس عن الإندي 10, بالإضآفة الى الّغة العربية فهناك شبه سفر مقآلآت عن كيفية استخدآم الإندي 10,, لذلك اشجعك بقوة اخي الكريم,, :bye1:

حسنا,, ستبدئ غدا,, ؟ ان شاء الله
لا بئس,, على كل سأكون بإنتظآرك ان شاء الله ولا تنسى اخي الحبيب بعد اذنك ان تضع الخطوآت وآحدة تلوة الأخرى حتى افهم :oops:

الله يبارك فيك ويرفع قدرك في الدآرين, اللهم آمين,,
ان نويت ان تبدئ 100% اخبرني بارك الله لك ورفع قدرك وزآدك من علمه

والسلام عليكم ورحمة الله وبركآته
فرّج همّ المهمومين يا الله
اللهم فك قيد اسرانا و اسرى المسلمين
الرد


التنقل السريع :


يقوم بقرائة الموضوع: بالاضافة الى ( 2 ) ضيف كريم