# Native Code > برنامه نویسی در Delphi > بانک های اطلاعاتی در Delphi > آموزش: آموزش Datasnap از ابتدا به زبان ساده

## golbafan

*سلام عزیزان* 
در این تاپیک میخوام بعد از تعریف تکنولوژی data-snap و ذکر فواید استفاده از اون، یک آموزش کامل و خلاصه هم ارائه کنم تا عزیزانی که دوست دارن نرم افزارهای چندلایه بنویسن بتونن استفاده کنن.

*لیست مباحثی که انشاالله در این تاپیک بررسی خواهد شد:*

1) مروری بر تکنولوژی DataSnap و معماری چند لایه
2) معرفی کامپوننت های مربوط به این تکنولوژی و کارایی هرکدام از آنها
3) روشهای ارتباط بین سرور و کلاینت
4) برقراری امنیت با استفاده از DataSnap
5) آموزش نوشتن یک برنامه ساده برای استفاده از متدهای سرور در کلاینت (بدون دیتابیس)
6) آموزش نوشتن یک برنامه 3 لایه ساده (کلاینت <-> سرور <-> دیتابیس)
7) آموزش نوشتن یک برنامه چند لایه با استفاده از وب سرویس ساده
8) آموزش نوشتن یک برنامه چند لایه با استفاده از وب سرویس مبتنی بر IIS
9) آموزش نوشتن یک برنامه چند لایه مبتنی بر REST و انتقال اطلاعات بر اساس JavaScript و JSON
10) نوشتن یک شبکه اجتماعی ساده با استفاده از DataSnap
11) ایجاد یک برنامه 4 لایه تحت وب با دلفی (کلاینت - وب سرور - دیتا اسنپ - دیتابیس)

----------


## golbafan

*تاریخچه و تعریف اجمالی:*
Data-snap یک تکنولوژی پیشرفته هست که اولین بار با اسم Midas در دلفی 3  ظهورپیدا کرد تا بتونه بین نرم افزارهای موجود در کامپیوترهای مختلف روی  شبکه ارتباط برقرار بکنه و در دلفی 6 پیشرفت عمده ای کرد و قابلیت های  فراوانی بهش اضافه شد و به اسم فعلی اش تغییر نام داد. بعد از اون ارتقاء  اساسی توسط شرکت Embarcadero در راد استودیو 2009 بود که این ابزار رو به  شکل امروزی اش تبدیل کرد. 
تا قبل از دلفی 2009 اساس کار data-snap بر پایه تکنولوژی dcom از  ماکروسافت بود ولی از دلفی 2009 به بعد، اساس کار TCP/IP شد و این در نوع  خودش انقلاب بزرگی بود. چراکه براحتی امکان استفاده از این تکنولوژی رو در  بستر اینترنت با پروتکل های HTTP و HTTPS و استفاده از ssl رو در اینترنت  فراهم ساخت. همچنین قابلیت احراز هویت در اینترنت (authentication) و  سازگاری با db-express اضافه شد. در نسخه های جدید و با ظهور فایرمانکی،  امکان ارتباط کلاینت های موبایل و ایجاد شبکه های اجتماعی توسط این  تکنولوژی فراهم شد. همچنین در دلفی xe8 به بعد امکاناتی مثل رمز نگاری RSA و  فشرده سازی داده با استفاده از Zlib فراهم شد.
*
برخی امتیازهای اساسی data-snap:*
1- این تکنولوژی امکان تولید نرم افزار های چند لایه و امن رو فراهم میکنه.
2- امکان اتصال هزاران کلاینت به سرور داده رو بدون نگرانی از تداخل داده و افت سرعت فراهم میکنه
3- کلاسها و متدهای سرور براحتی و بصورت اتومات میتونه در کلاینت ایجاد بشه و در کد کلاینت مورد استفاده قرار بگیره (نیاز به نوشتن مجدد نیست)
4- این تکنولوژی برای انتقال امن داده ها از JSON استفاده میکنه.
5- مدیریت حافظه در سرور و همچنین مدیریت برنامه چند رشته ای (Thread Pool) بصورت اتوماتیک هست.
6- تغییراتی که کلاینت ها قراره روی داده انجام بدن بصورن موازی پردازش میشه و بنابر این مشکلی برای در صف بودن پردازش ها نیست. (مگر اینکه تعداد پردازشهای موازی رو محدود کنیم)
7- امکان استفاده از انواع وب سرویس ها رو با کمک تکنولوژی WebBroker فراهم میکنه
8- اگر در سرور و کلایت از فایروال استفاده بشه، میتونه با ایجاد تونل ارتباطی و پروکسی کار ارتباط گیری رو براحتی انجام بده
9- این تکنولوژی امکانی رو فراهم میکنه که کلایت و سرور میتونن هردو در یک اپلیکیشن هم باشن!
10- برنامه نویسی برای شبکه های اجتماعی پرسرعت و امن مثل تلگرام رو خیلی راحت میکنه

----------


## golbafan

*1) مروری بر تکنولوژی DataSnap و معماری چند لایه

معماری datasnap:*
هدف اصلی این تکنولوژی بطورکلی در راستای تولید نرم افزارهای چند لایه  تعریف میشه. در ساده ترین حالت میشه معماری چند لایه رو بصورت 3 لایه در  نظر گرفت:
1- لایه دادگان (data tier) : این لایه از دسترس کاربران مخفی هست و محل ذخیره سازی داده ها در دیتابیس هست
2- لایه منطق (logic tier) :این لایه میتونه یک سرور باشه که کلاینت ها بهش  دسترسی دارن و کلیه کارهای اساسی و ارتباط با دیتابیس رو انجام میده
3- لایه ارائه (presentation tier) : این لایه برای دریافت اطلاعات مورد  نیاز از کاربر و ارسال به لایه منطقی طراحی میشه و در کلاینت ها قرار داره  همچنین نتایج و خروجی ها در این لایه مشاهده میشه.
3-thierLayers_2.png

اگه مطلب بالا رو برای datasnap تعمیم بدیم به شکل زیر میرسیم:
DataSnapArch.jpg

1- لایه منبع داده: این لایه در واقع سروری رو شامل میشه که دیتابیس ما در  اون قرار داره. میتونیم مثلا در سرور A یک یا چند دیتابیس مورد نظرمون رو  نصب کنیم.
2- لایه نرم افزار سرور data-snap: این لایه همون logic-tier هست که نرم  افزار مادر (سرور) اونجا نصب میشه و بدلایل امنیتی بهتره در یک سرور  جداگانه از سرور دیتابیس نصب بشه.
3- لایه کلاینت که میتونه بصورت یک صفحه وب یا یک نرم افزار ویندوزی باشه...

03000003.jpg

سوال:
1) خب حالا چرا ما از این معماری های پیچیده استفاده میکنیم؟
2) چرا بهتره سرورهای هر لایه از هم جدا باشند؟

----------


## golbafan

قبل از شروع مبحث اصلی بزارید به سوالات در پست قبلی پاسخ بدم:
*
1) چرا ما از این معماری های پیچیده استفاده میکنیم؟*
خیلی از برنامه نویسهای مبتدی وقتی صحبت از یک نرم افزار دیتابیسی به میون  میاد تصور میکنن بهترین راه حل نوشتن یک برنامه جامع و کامله که به همراه  یک دیتابیس با طراحی بی نقص بتونه تمام مشکلات مشتری رو مرتفع کنه. 
خب البته این مورد موقعی درسته که ما نیاز به هیچ گونه شبکه کامپیوتری  نداشته باشیم. وقتی پای شبکه و بهره برداری چندین کاربر بصورت همزمان مطرح  میشه خیلی مسایل مختلفی پیش میاد که دیگه نمیشه به همین راحتی با اتصال نرم  افزار به دیتابیس کار رو پیش برد.
یکی از مهم ترین مسایلی که پیش میاد، تامین امنیت برای دیتابیس هست. اگر  نرم افزاری که در مقابل کاربران قرار داره مستقیما به دیتابیس وصل باشه  (حالا دیتابیس هرجا میخواد باشه) خیلی راحت میشه به دیتابیس و نام کاربری و  رمز عبور اون دسترسی پیدا کرد و هرگونه خرابکاری رو انجام داد. (مخصوصا  برای mssql)
مورد با اهمیت دوم اینه که با روش عادی (دو لایه) نمیتونیم انتظار داشته  باشیم سرور داده با سرعت مناسب و استفاده کم از منابع سیستم کارش رو انجام  بده. چون هر کلاینتی که یک کانکشن جداگانه ایجاد میکنه و یا کوئری خاصی رو  ارسال میکنه در واقع پردازش سنگینی رو روی دیتابیس تحمیل میکنه. همچنین  دیتابیس معمولا مجبوره تا به سرانجام رسوندن دستورات کلاینت اول از خدمت  رسانی به کلاینت دوم صرف نظر کنه و این میشه همون انتظار در صف.
فرض کنید 100 تا کلاینت داشته باشیم و هرکدوم بخوان یک گزارش ماهیانه از  دیتابیس بگیرن! فکر کنید چی پیش میاد؟ حالا اگر مثل شبکه های اجتماعی تعداد  به میلیونها کلاینت برسه چی؟
نکته سوم بحث دسترسی کاربران به داده هاست. اگر از معماری ساده استفاده  بشه، تنها راه مدیریت کلاینت ها برای عدم دسترسی به دیتابیس اینه که  کاربران رو در سطح دیتابیس محدود کنیم یعنی مجبوریم برای هر کلاینت یک  کاربر با رمزعبور در دیتابیس تعریف کنیم و موقع اتصال کاربر به دیتابیس رمز  عبور رو از خود کاربر بپرسیم!  :قهقهه: 
یا اینکه همه کلاینت ها رو با استفاده از کاربر ادمین دیتابیس (همون sa در  mssql یا مثلا root در mysql) وصل کنیم و دسترسی ها رو در سطح کلاینت انجام  بدیم و کلی کدنویسی اضافه انجام بدیم. البته این روش بسیار ناکارامد هست  چون با توجه به دسترسی کلاینت به دیتابیس، کاربران حرفه ای میتونن دسترسی  خودشون رو در دیتابیس ویرایش کنند!  :قهقهه: 
*
2) چرا بهتره سرورهای هر لایه از هم جدا باشند؟*
اولین و مهمترین دلیل بخاطر امنیت است: همونطور که در جواب سوال قبلی مطرح  کردم، کلاینت نباید از مسیر سرور دیتابیس باخبر باشه. البته اگر از مسیر  سرور پردازشگر (لایه منطقی میانی) خبر داشته باشه اتفاق خاصی پیش نخواهد  آمد چون دسترسی فقط میتونه محدود بشه به پورت شونده نرم افزار سرور.
دوم بخاطر سرعت: بین نرم افزار سرور و دیتابیس، در حالت کلی فقط یک کانکشن  ایجاد میشه بنابراین سرعت خوبی رو شاهد هستیم. اما به هر حال پردازش هایی  رو که نرم افزار سرور قراره انجام بده خیلی بهتره که از پردازشهای دیتابیس  جدا کنیم. با این کار میتونیم خیال خودمون رو از تعداد پردازشهای بالا و  همزمان راحت کنیم.

----------


## golbafan

*2) معرفی کامپوننت های مربوط به این تکنولوژی و کارایی هرکدام از آنه
 
معرفی اجزای اصلی data-snap:*

تکنولوژی دیتا اسنپ شامل دو بخش اصلی میشه:
1) بخش مربوط به نرم افزار سرور : شامل کامپوننت های سرور
2) بخش مربوط به نرم افزار کلاینت : شامل کامپوننت های کلاینت
همچنین یک بخش فرعی که در واقع تامین کننده ارتباط دیتاست که معمولا و بصورت پیشفرض از کامپوننت های dbExpress استفاده میشه

alll.png

----------


## golbafan

*کامپوننت های سرور
*
*
کامپوننت DSProxyGenerator*
 این کامپوننت همون طور که از اسمش پیداست جهت ایجاد  کلاسهای مورد نیاز    کلاینت برای اتصال به سرور از طریق proxy بوده و میتونه  بطور اتومات فایل    یونیت جدیدی به همراه تمام متدهای مورد نیاز رو ایجاد  کنه:
یک نمونه کد معروف رو اینجا میارم:
var
  SqlConnection: TSqlConnection;
  DSConnectionMetaDataProvider: TDSConnectionMetaDataProvider;
  ProxyGen: TDSProxyGenerator;

begin
  SqlConnection := TSqlConnection.Create(nil);
  try
    SqlConnection.DriverName := 'DataSnap';
    SqlConnection.Params.Text := 'DriverName=DataSnap'+#13#10+'Port=211'+#13#10;
    DSConnectionMetaDataProvider := TDSConnectionMetaDataProvider.Create(SqlConnection  );
    DSConnectionMetaDataProvider.SQLConnection := SqlConnection;
    // DSProxyGenerator ایجاد کامپوننت
    ProxyGen := TDSProxyGenerator.Create(SqlConnection);
    ProxyGen.MetaDataProvider := DSConnectionMetaDataProvider;
    // نام متد هایی که میخواهیم از طریق پراکسی انجام بشن و در یونیت خروجی بیان
    ProxyGen.ExcludeMethods := 'EchoString;ReverseString';
    ProxyGen.Writer := sDelphiDBXProxyWriter;
    // محل ذخیره سازی فایل خروجی
    ProxyGen.TargetDirectory := 'C:\';
    ProxyGen.TargetUnitName := 'GeneratedProxy.pas';
    // نوشتن فایل خروجی
    ProxyGen.Write;
  finally
    SqlConnection.Free;
  end;
end.
*
کامپوننت DSServerMetaDataProvider*
این کامپوننت امکان ارتباط سایر کامپوننت ها به کامپوننت سرور رو فراهم    میکنه. اطلاعات سرور میتونه بصورت یک ابرداره (metadata) برای سایر مقاصد    مورد نیاز مورد استفاده قرار بگیره. 
این کامپوننت به تنهایی کار خاصی نمیکنه و صرفا جهت برقراری ارتباط هست.    (شبیه کاری که data-source میکنه و مثلا table رو به db-grid وصل میکنه)

*کامپوننت DSRestConnection*
از این کامپوننت برای ایجاد اتصالات مبتنی بر تکنولوژی REST برای استفاده    در اینترنت استفاده میشه. امکان استفاده از ISAPI رو فراهم میکنه و یک    ارتباط 2 طرفه بین وب سرویسها و کلاینت ها فراهم میکنه. با این کامپوننت در    آینده خیلی کار خواهیم داشت. اما قبل از اون، مطالب مربوط به REST و   ISAPI  رو جداگانه جستجو و مطالعه کنید. البته من موقع آموزش استفاده از    DSRestConnection نحوه کانفیگ سرویس ISAPI رو برای استفاده در data-snap    آموزش خواهم داد.

*کامپوننت DSRestMetaDataProvider*
این کامپوننت هم مثل سایر MetaDataProvider ها در واقع برای ایجاد ارتباط    هست. اینبار این کامپوننت برای ایجاد ارتباط بین سایر کامپوننت ها با    کامپوننت DSRestConnection مورد استفاده قرار میگیره.

*کامپوننت DSClientCallbackChannelManager*
میشه گفت یکی از هنرهای زیبای تکنوولژی دیتا اسنپ همین کامپوننت هست. این    کامپوننت میتونه ارتباطات بین سرورها و کلاینت هایی رو مدیریت کنه که روی    یک بستر ارتباطی قرار دارند. البته بدون اینکه تداخلی ایجاد بشه. مدیریت    پاسخ های کلاینت و سرور به یکدیگر میتونه روی یک آدرس و پورت مشابه و در    کانالهای مشابه با ID های متفاوتی انجام بشه و اینکار بصورت پردازش موازی  و   بدون تداخل اتفاق خواهد افتاد. سرور حتی قادره پاسخ به کانال های  متفاوت   رو با یک کانال انجام بده! همچنین سرور میتونه با استفاده از این  کامپوننت   پیامهای خودشو با ارتباط از نوع peer-to-peer با کلاینت ها  درمیون بزاره.

*کامپوننت DSServer*
این کامپوننت در همه پروژه های دیتا-اسنپ استفاده میشه. در واقع به همراه    کامپوننت DSServerClass هسته اصلی نرم افزار سرور رو تشکیل میدن
کارش روشن و خاموش کردن نرم افزار سرور، مدیریت طول عمر کانکشن ها و انتقال دیتا است.

*کامپوننت DSServerClass*
همونطور  که گفتم، این کامپوننت به همراه DSServer هسته نرم افزار سرور   دیتا-اسنپ  رو تشکیل میدن. این کامپوننت در واقع کلاس سرور رو به همراه   تمامی متدهایی  که قراره توسط کلایت فراخوانی بشه در خودش بارگیری میکنه.   در نهایت متدهای  مورد نظر رو برای استفاده در بخش های دیگه پابلیش میکنه.   اگه به ابتدای پست  نگاه کنید در اون مثالی که آوردم یک همچین مطلبی   هست:// نام متد هایی که میخواهیم از طریق پراکسی انجام بشن و در   یونیت خروجی بیان
    ProxyGen.ExcludeMethods := 'EchoString;ReverseString';در   اینجا متدهای EchoString و ReverseString که به عنوان مثال در کلاس سرور   نوشته شدن رو تونستیم توسط DSProxyGenerator فراخوانی کنیم. 
توابع و متد های این کلاس میتونن توسط کلاینت ها فراخوانی بشن و عملیات در سرور اتفاق بیوفته. 
یکی  از مزایای DataSnap اینه که میتونید متدهای موجود در کلاس سرور رو   بصورت  اتوماتیک در کلاینت ایجاد کنید و نیازی به نوشتن دوباره اونها نیست.   (این  کار مهم رو در آینده وقتی به بخش نوشتن کلاینت رسیدیم آموزش میدم)

*کامپوننت DSCertFiles*
این کامپوننت موقع استفاده از SSL و پروتکل HTTPS استفاده میشه و فایل   امضای دیجیتال رو برای سرور مورد نظر بارگیری میکنه. امضاهای دیجیتال مورد   استفاده تحت استاندارد X.509 هستند.
موقع استفاده از این کامپوننت دقت کنید که رمز عبور فایل امضای دیجیتال رو   در زمان اجرا وارد کنید. اگر زمان طراحی این رمز رو وارد کنید امکان هک  شدن  سرور شما بیشتر میشه. 
برای مطالعه بیشتر باید مباحث مربوط به PE رو جستجو کنید.

*کامپوننت DSAuthenticationManager*
این کامپوننت همونطور که از اسمش پیداست برای چک کردن اعتبار و سطح دسترسی  کاربران و سایر مجوزها مورد استفاده قرار میگیره. یک کامپوننت حرفه ای به  حساب میاد و اجازه میده تمامی رول های مورد نیازتون رو ایجاد کنیدو برای هر  کدوم یک سری دسترسی ایجاد کنید و به کاربران مختلف ارائه کنید. میتونید  برای هر رول یک سری از متدهای سرور رو دسترسی بدید و خیلی کارهای دیگه.  میشه گفت این کامپوننت از با اهمیت ترین اجزای DataSnap در راستای ایجاد  امنیت بالاست. کار باهاش خیلی راحته و خطای انسانی رو برای نوشتن بخش لاگین  و دسترسی ها از بین میبره.

*کامپوننت DSRESTWebDispatcher*
این کامپوننت برای ارسال درخواست های REST به وب سرویس بکار میره. همچنین  امکان پاسخ گویی به درخواست های REST رو برای کامپوننت DSRESTServer که  نوعی  DSServer هست فراهم میکنه. 
بنابراین این دو کامپوننت رو معمولا با هم استفاده میکنیم

*کامپوننت DSHTTPServiceProxyDispatcher*
این کامپوننت امکان استفاده از پروکسی رو برای نرم افزار سمت سرور روی پروتکل HTTP فراهم میکنه و وقتی مورد استفاده قرار میگیره که ما نمیخوایم از تکنولوژی WebBroker استفاده کنیم. معمولا وقتی از وب سرویس ها استفاده میکنیم بکار میاد. مثلا موقع استفاده از سرویس های وب IIS یا مثلا SOAP
این کامپوننت میتونه تنظیمات پروکسی رو بصورت یک فایل زیپ شده برای کلاینت هایی که در پلتفرم های دیگه (مثلا اندروید) هستند نیز بسازه و ارسال کنه

*کامپوننت DSProxyDispatcher*
این کامپوننت مشابه کامپوننت DSHTTPServiceProxyDispatcher است با این تفاوت که برای وب اپلیکیشن های نوشته شده با تکنولوژی WebBroker استفاده میشه

*کامپوننت DSTCPServerTransport*
این کامپوننت امکان اتصال کلاینت به سرور رو از طریق پروتکل TCP/IP فراهم میکنه و یکی از پرکاربردترین کامپوننت های DataSnap بشمار میره. 
این کامپوننت سوکت بیس هست و میتونید عملیات رو از طریق IP و پورت دلخواه (پیشفرض 211) انجام بدید. 

*کامپوننت DSConnectionMetaDataProvider*
این کامپوننت هم مثل سایر MetaDataProvider ها در واقع برای ایجاد ارتباط     هست. اینبار این کامپوننت برای ایجاد ارتباط بین سایر کامپوننت ها با     کامپوننت SqlConnection مورد استفاده قرار میگیره. در مثالی که در ابتدای همین پست براتون زدم، یک *DSProxyGenerator* از طریق *DSConnectionMetaDataProvider* به خواص مربوط به *SqlConnection* متصل شده:
DSConnectionMetaDataProvider := TDSConnectionMetaDataProvider.Create(SqlConnection  );
    DSConnectionMetaDataProvider.SQLConnection := SqlConnection;
    ProxyGen := TDSProxyGenerator.Create(SqlConnection);
    ProxyGen.MetaDataProvider := DSConnectionMetaDataProvider;

*کامپوننت DSHTTPService*
این کامپوننت این امکان رو میده که متدهای موجود در سرور بتونن از طریق کلاینت های مبتنی بر مرورگر فراخوانی بشن. این کار میتونه با کمک تکنولوژی REST و یا JSON صورت بگیره. در صورت نیاز میتونید این کامپوننت رو به همراه DSAuthenticationManager برای بهره بردن از امکانات هویت سنجی نیز بکار ببرید.

*کامپوننت DSHTTPServiceFileDispatcher*
این کامپوننت امکان ارسال فایل و درخواست اون رو از طریق وب سرویس ها فراهیم میکنه. وقتی از طرف کلاینت در پروتکل http یک فایل درخواست میشه، این کامپوننت مسئول پاسخگویی است و فایل ها رو میتونه از مسیر RootDirectory و یا سایر مسیرهای وب بخونه.

*کامپوننت DSHTTPWebDispatcher*
این کامپوننت برای این هست که درخواست های REST و HTTP Tunnel رو پاسخ بده. از این کامپوننت در کنار DSHTTPServer استفاده میشه و امکان پاسخ گویی رو تحت پروتکل HTTP و از طریق REST فراهم میکنه

----------


## golbafan

*کامپوننت های dbExpress*

خب شاید به نظر برسه که من باید اول کامپوننت های سمت کلاینت DataSnap رو توضیح میدادم. ولی این کار رو نکردم  :چشمک: 
در ادامه دلیلشو توضیح میدم...

*کامپوننت TSQLConnection*
از این کامپوننت برای برقراری ارتباط با دیتابیس ها استفاده میکنیم. این کامپوننت میتونه به انواع مختلف دیتابیس (MS. SQL Server , MySQL , Oracle و ...) وصل بشه. اما خاصیتی داره که برای کار ما خیلی اهمیت داره و اون خاصیت اینه که امکان اتصال به درایور DataSnap رو هم برای ما فراهم میکنه. برای این کار باید خاصیت Driver رو بزارید روی حالت DataSnap بعد میبینید که یک سری خواص مربوط به اتصال به سرور رو براتون نمایش میده
32.jpg
دایره قرمز رنگ مشخصات اتصال به سرور رو نشون میده...

----------


## golbafan

سلام به عزیزان دنبال کننده تاپیک...  :قلب: 

در پست قبلی کامپوننت *TSQLConnection* رو معرفی کردم. این کامپوننت در گروه *dbExpress* قرار داره اما کاربردش خیلی بیشتر از یک دیتابیس کانکشن ساده هست. کاربرد اصلی این کامپوننت برای کار با DataSnap در سمت کلاینت بوده و یکی از مهمترین و ضروری ترین کامپوننتهای خانواده DataSnap به شمار میره. 
این کامپوننت میتونه کلاسهای سمت سرور رو برای کلاینت ایجاد کنه تا کلاینت با استفاده از توابع ایجاد شده در یک یونیت مربوط به خودش بتونه همون توابع رو در سرور صدا بزنه...

برای اینکه با اهمیت این مساله آشنا بشین یک برنامه ساده رو مثال میزنم. 
البته برخی قسمت ها رو فعلا توضیح نمیدم تا از مسیر اصلی منحرف نشیم و در جای خودش آموزش میدم. فعلا فقط میخوایم روی *TSQLConnection* تمرکز کنیم
میخواهیم یک برنامه ماشین حساب سرور داشته باشیم که چهار عمل اصلی ریاضی ( + - * / ) رو سمت سرور انجام بده و نتیجه رو به کلاینت برگردونه...

نرم افزار سرور رو اینطور شروع میکنیم:

1- در دلفی مسیر منوی File->New->Other رو استفاده کنید.
2- دنبال شاخه DataSnap بگردید و مثل شکل زیر گزینه DataSnap Server رو انتخاب کنید (اون دو گزینه دیگه رو بعدا آموزش میدم که چی هست) و تایید رو بزنید.
1.jpg
3- فعلا میخوایم با ساده ترین حالت ممکن شروع کنیم. پس در این مرحله گزینه Console Application رو انتخاب کنید و برید مرحله بعد.
2.jpg
4- همونطور که در شکل زیر میبینید به مرحله انتخاب تکنولوژیهای مورد نیاز رسیدیم. فعلا کاری با این نداریم و با همون حالت پیشفرض (یعنی tcp/ip) و بدون استفاده از سایر امکانات کار میکنیم (این پنجره نیاز به آموزش بیشتری داره که بعدا تک تک موارد رو مفصل توضیح میدم)
3.jpg
5- پورت TCP/IP رو اینجا مشخص میکنیم. یعنی پورتی که کلاینت ها بتونن با سرور ارتباط بگیرن. پیشفرض رو همون 211 میزاریم و میریم مرحله بعد.
4.jpg
6- در مرحله بعد 3 تا گزینه مشاهده میکنیم. اینجا برای اینکه بتونیم استاندارد ترین حالت رو داشته باشیم و خودمون رو هم تو زحمت کدنویسی های اضافه نندازیم گزینه سوم TDSServerModule رو انتخاب 
میکنیم و پایان رو میزنیم تا فرم ها و یونیت های لازم ایجاد بشن.
5.jpg

پروژه ای رو که ایجاد شده یک جایی ذخیره کنید. من پروژه رو به اسم CalcServer ذخیره کردم.

چهار تا فایل برای شما ایجاد میشه. باید بریم سراغ یونیت ServerMethodsUnit1 و داخلش رو ببینیم:
unit ServerMethodsUnit1;

interface

uses System.SysUtils, System.Classes, System.Json,
    DataSnap.DSProviderDataModuleAdapter,
    Datasnap.DSServer, Datasnap.DSAuth;

type
  TServerMethods1 = class(TDSServerModule)
  private
    { Private declarations }
  public
    { Public declarations }
    function EchoString(Value: string): string;
    function ReverseString(Value: string): string;
  end;

implementation


{$R *.dfm}


uses System.StrUtils;

function TServerMethods1.EchoString(Value: string): string;
begin
  Result := Value;
end;

function TServerMethods1.ReverseString(Value: string): string;
begin
  Result := System.StrUtils.ReverseString(Value);
end;

end.

همونطور که میبینید در این یونیت 2 تا متد بصورت نمونه و اتوماتیک ایجاد شده: ReverseString و EchoString

ما میخوایم متد Calc رو برای مثال خودمون اضافه کنیم. قبلش برای ساده شدن کدها این متد های نمونه رو حذف میکنم.
unit ServerMethodsUnit1;

interface

uses System.SysUtils, System.Classes, System.Json,
  DataSnap.DSProviderDataModuleAdapter, DataSnap.DSServer, DataSnap.DSAuth;

type
  TServerMethods1 = class(TDSServerModule)
  private
    { Private declarations }
  public
    { Public declarations }
    function Calc(Num1, Num2: Double; Oprt: Integer): Double;
  end;

implementation

{$R *.dfm}

uses System.StrUtils;

function TServerMethods1.Calc(Num1, Num2: Double; Oprt: Integer): Double;
begin
  Result := 0;
  case Oprt of
    0:
      Result := Num1 + Num2;
    1:
      Result := Num1 - Num2;
    2:
      Result := Num1 * Num2;
    3:
      if Num2 <> 0 then
        Result := Num1 / Num2;
  end;
end;

end.

برنامه سمت سرور به همین راحتی انجام شد...* اجراش میکنیم و میزاریم فعلا همینجوری باز بمونه
*6.jpg

----------


## golbafan

حالا باید نرم افزار کلاینت رو بنویسیم.

1- یک پروژه جدید از نوع vcl forms application ایجاد میکنیم و با نام دلخواه ذخیره میکنیم
2- فرم اصلی Form1 رو شامل این کامپوننت های مورد نیاز مثل عکس زیر میکنیم:
8.jpg
همونطور که میبینید از SQLConnection1 اینجا استفاده شده.
مراحل 3 تا 5 برای ایجاد اتوماتیک یک یونیت هست که امکان استفاده از توابع سرور رو در کلاینت به ما میده:

3- مشخصه Driver رو برای SQLConnection1 روی حالت DataSnap میزاریم. همونطور که قبلا گفتم یک سری خاصیت به کامپوننت اضافه میشه. مثلا میتونیم پورت اتصال رو انتخاب کنیم.
 اگر از پورت 211 پیشفرض در سرور استفاده کرده باشید، اینجا نیاز به تغییرات نداریم.

4- مشخصه LoginPromp مربوط به SQLConnection1 رو False کنید و مشخصه Connected رو True کنید. (نرم افزار سرور که در پست قبلی نوشتیم باید حتما در حال اجرا باشه و سرور Start شده باشه)

5- روی کامپوننت SQLConnection1 راست کلیک کرده و گزینه Generate DataSnap Client Classes رو بزنید.
بطور خودکار یک یونیت ایجاد میشه. این یونیت رو در uses های یونیت مربوط به Form1 اضافه میکنیم.
unit Unit2;

interface

uses System.JSON, Data.DBXCommon, Data.DBXClient, Data.DBXDataSnap, Data.DBXJSON, Datasnap.DSProxy, System.Classes, System.SysUtils, Data.DB, Data.SqlExpr, Data.DBXDBReaders, Data.DBXCDSReaders, Data.DBXJSONReflect;

type
  TServerMethods1Client = class(TDSAdminClient)
  private
    FCalcCommand: TDBXCommand;
  public
    constructor Create(ADBXConnection: TDBXConnection); overload;
    constructor Create(ADBXConnection: TDBXConnection; AInstanceOwner: Boolean); overload;
    destructor Destroy; override;
    function Calc(Num1: Double; Num2: Double; Oprt: Integer): Double;
  end;

implementation

function TServerMethods1Client.Calc(Num1: Double; Num2: Double; Oprt: Integer): Double;
begin
  if FCalcCommand = nil then
  begin
    FCalcCommand := FDBXConnection.CreateCommand;
    FCalcCommand.CommandType := TDBXCommandTypes.DSServerMethod;
    FCalcCommand.Text := 'TServerMethods1.Calc';
    FCalcCommand.Prepare;
  end;
  FCalcCommand.Parameters[0].Value.SetDouble(Num1);
  FCalcCommand.Parameters[1].Value.SetDouble(Num2);
  FCalcCommand.Parameters[2].Value.SetInt32(Oprt);
  FCalcCommand.ExecuteUpdate;
  Result := FCalcCommand.Parameters[3].Value.GetDouble;
end;


constructor TServerMethods1Client.Create(ADBXConnection: TDBXConnection);
begin
  inherited Create(ADBXConnection);
end;


constructor TServerMethods1Client.Create(ADBXConnection: TDBXConnection; AInstanceOwner: Boolean);
begin
  inherited Create(ADBXConnection, AInstanceOwner);
end;


destructor TServerMethods1Client.Destroy;
begin
  FCalcCommand.DisposeOf;
  inherited;
end;

end.



6- حالا میتونیم مشخصه Connected مربوط به SQLConnection1 رو False کنیم.

7- میتونیم در فرم اصلی اینجوری کد بزنیم:
uses Unit2;

// فراخوانی تابع مربوطه از سرور
procedure TForm1.Button1Click(Sender: TObject);
var
  num1, num2, res: Double;
  oprt: Integer;
  SMC: TServerMethods1Client;
begin
  num1 := StrToFloat(LabeledEdit1.Text);
  num2 := StrToFloat(LabeledEdit2.Text);
  oprt := RadioGroup1.ItemIndex;
  SMC := TServerMethods1Client.Create(SQLConnection1.DBXCon  nection);
  res := SMC.Calc(num1, num2, oprt);
  LabeledEdit3.Text := FloatToStr(res);
  FreeAndNil(SMC);
end;

// اتصال به سرور هنگام ایجاد فرم
procedure TForm1.FormCreate(Sender: TObject);
begin
  SQLConnection1.Connected:=True;
end;

حالا برنامه رو اجرا و تست میکنیم:
9.jpg

----------


## golbafan

*کامپوننت های کلاینت (ِDataSnap Client)*

در پست های قبلی کامپوننت های سرور و همچنین کامپوننت TSQLConnection رو معرفی کردم و با کمک اونها یک برنامه ساده کلاینت سرور مثال زدم. اما هنوز کارهای زیادی برای انجام دادن داریم. برای ادامه بهتره با معرفی کامپوننت های کلاینت پیش بریم و البته کامپوننت های گروه Data Access

*کامپوننت DSProviderConnection*
این کامپوننت برای برقراری اتصال دیتابیس های کلاینت به سرور استفاده میشه و یک رابط بین ClientDataset و SQLConnection ایجاد میکنه. این کامپوننت همچنین وظیفه ارسال یک سری دستورات رو به سرور به عهده داره. مثلا وقتی شما در کلاینت یک رکورد رو تغییر میدید، باید از متد ClientDataset.ApplyUpdates استفاده کنید تا تغییرات به سرور ارسال بشه. اما در حقیقت این کار توسط *DSProviderConnection* و با استفاده از فراخوانی متد *AS_ApplyUpdates* از سمت سرور انجام میشه.

*کامپوننت TDCOMConnection*
این کامپوننت همونطور که از اسمش پیداست جزء گروه Connection هاست و شبیه به TSQLConnection عمل میکنه یعنی برای اتصال به سرور استفاده میشه. البته با عمون تکنولوژی قدیمیتر DataSnap یعنی DCOM. استفاده از این کامپوننت یک سری دردسر هایی داره. مثلا باید روی مبحث فایروال و تعریف اون وقت بیشتری صرف کنید. همچنین باید روی تمام کلاینت ها سرویس DCOM مورد نظر (که اینجا نرم افزار سرور هست) رو رجیستر کنید...

*کامپوننت TSocketConnection*
این کامپوننت هم در گروه اتصالات قرار داره بااین تفاوت که برای برقراری ارتباط با سرور، از پروتکل TCP/IP و همچنین سوکت بهره میبره. این کامپوننت نسبت به TDCOMConnectio خیلی ساده تر استفاده میشه و بنظر میرسه سرعت خوبی هم داشته باشه. این کامپوننت میتونه پیامهای بین سرور و کلاینت رو دیکد و انکد کنه و با این روش امنیت رو برقرار میکنه. نکته ای که هست اینه که باید نرم افزار یا سرویس ScktSrvr.exe حتما در کامپیوتر سرور در حال اجرا باشه.

*کامپوننت TSimpleObjectBroker* 
فرض کنید یک سرور دارید که لایه میانی شماست و نرم افزار سمت سرور روش نصبه که به دیتابیس وصل شده. از طرفی هم کلاینت ها همگی به این لایه میانی و نرم افزار سمت سرور وصل هستند. حالا با این فرض اگر سرور لایه میانی به هر دلیلی مشکلی براش پیش بیاد و از چرخه خارج بشه چی میشه؟؟؟
کل سیستم میخوابه...
cloud_dir.jpg

برای جلوگیری از این مساله معماری پردازش ابری به کمک ما میاد و ما بجای استفاده از یک سرور ، از چندین و چند سرور در لایه میانی استفاده میکنیم. کار کامپوننت *TSimpleObjectBroker* اینه که این سرورها رو مدیریت کنه و بصورت اتوماتیک کلاینت ها رو به سمت سروری که وضعیت خوبی داره هدایت کنه. مثلا اگر یکی از سرور های لایه میانی از کار افتاد یا اینکه بیشتر از ظرفیتش پر شد، کلاینت های بعدی رو روی سرور جدید هدایت میکنه.

*کامپوننت TWebConnection*
این کامپوننت هم میتونه برای اتصال کلاینت به سرور به کار بره با این تفاوت که این کامپوننت از پروتکل http استفاده میکنه و بصورت پیشفرض روی پورت 80 تنظیم میشه که البته امکان تغییر دادن پورت پیشفرض هست ولی باید برای کارکرد صحیح سیستم در فایروال اون پورت رو تعریف کنید. برای استفاده در کلاینت هایی که قراره به سرور وصل بشن باید کتابخانه Wininet.dll در کلاینت موجود باشه. (اگر IE نسخه 3 به بعد در کلاینت نصب یاشه این کتابخانه هم در کلاینت موجوده) همچنین سرور های ویندوزی باید شامل IIS4 به بالا باشند.

*کامپوننت TConnectionBroker*
وقتی از جندین کانکشن مختلف این کامپوننت در واقع برای راحت کردن کار برنامه نویسی استفاده میشه و مثل یک واسط عمل میکنه. وقتی روی کلاینت تعداد زیادی Client_Dataset وجود داشته باشه و ما بخوایم در زمان اجرا کانکشن همه رو عوض کنیم و مثلا از حالت TCP به حالت HTTP ببریم باید کدی بنویسیم تا بیاد کانکشن تک تک این کلاینت دیتا ست ها رو تغییر بده. اما با استفاده از *TConnectionBroker* میتونیم برای تغییر دادن کانکشن همه کلاینت دیتاسِت های موجود بیاییم فقط مشخصه مربوط به *TConnectionBroker* رو تغییر بدیم. 
همچنین این کامپوننت میتونه رویدادهای مربوط به کانکشن های مختلف روی سرور رو هم تجمیع کنه. مثلا نیازی نیست برای*TWebConnection و* *TSocketConnection* بطور جداگانه رویدادهای *AfterConnect* رو بنویسید و میتونید یک بار برای *TConnectionBroker*  این رویداد رو بنویسید.

*کامپوننت TSharedConnection*
این کامپوننت برای اتصال به سرورهایی بکار میره که شامل بیش از یک DataModule باشند. اگر از این کامپوننت استفاده نکنید باید برای اتصال کلاینت به سرور، به تعداد دیتا ماژول های موجود در سمت سرور ، یک کانکشن از کلاینت به سرور ایجاد کنید. مثلا اگر سرور شما 3 تا دیتاماژول داشته باشه هرکلاینت باید 3 تا کانکشن برقرار کنه. اما با استفاده از این کامپوننت شما فقط یک کانکشن به سرور میزنید و درواقع همه کانکشن هایی رو که میخواستید بزنید با همین کانکشن جدید تجمیع شده زده اید.

*کامپوننت TLocalConnection*
این کامپوننت خیلی استفاده زیادی نداره. برای مواقعی بکار میره که نرم افزار سرور و کلاینت در هم ادغام باشند. (کامپوننت های سرور و کلاینت هر دو در یک نرم افزار باشند و اتصال ریموت نداشته باشیم)

----------


## yaser.barati

اقای گلبافان سلام و خسته نباشید بابت این تاپیک عالی ممنونم.فقط اینو دیگه ادامه نمیدین؟

----------


## golbafan

سلام به همه دوستان و دنبال کنندگان این تاپیک.
حتما ادامه مباحث رو آموزش میدم.
موفق باشید.

*پست شماره 10# تکمیل شد*

----------


## golbafan

*3) روشهای ارتباط بین سرور و کلاینت

*در این قسمت با انواع روشهای ارتباط بین کلاینت و سرور آشنا خواهیم شد.
لیست روشهایی که معمولا استفاده میشه:

1- TCP/IP
2- COM/DCOM
3- Http/Https

----------


## golbafan

اول از همه تصمیم گرفتم تا رویکرد استفاده از COM/DCOM رو شرح بدم و بزاریمش کنار. چون این رویرد در حال حاضر خیلی کارایی نداره و اگر هنوز هم میبینیم که داره در DataSnap استفاده میشه صرفا بخاطر سیاست های شرکت سازنده است که میخواد نسخه های قدیمی رو ساپورت کنه. پس ممکنه مثل bde بعد یک مدت کلا کنار گذاشته بشه.

همونطور که میدونید، استاندارد تکنولوژی com توسط ماکروسافت در سال 1993 برای ایجاد ارتباط بین نرم افزارهای مختلف پدید اومد. خیلی از تکنولوژیهای دیگه مثل activex و dcom از همین تکنولوژی مشتق شده اند.
میشه گفت com در واقع پدر Net. هست

 در نسخه های اولیه datasnap برای برقراری ارتباط نرم افزارها با همدیگه، از امکانات موجود در dcom استفاده شد و بعلت مسایل و مشکلات متعددی که بعدها مطرح شد و امکان استفاده از این استاندارد ها رو با مشکل مواجه کرد یواش یواش به حاشیه فرستاده شد.
روش dcom که مخفف Distributed Component Object Model هست در واقع امکان توضیع پردازشها رو بین چندین سیستم روی شبکه ایجاد میکنه و بین سیستم های مختلف ارتباط برقرار میکنه. در نسخه های قدیمی دلفی و datasnap ساده ترین راهی که برای توسعه دهندگان دلفی پیش رو بود استفاده از همین تکنولوژی ساخت ماکروسافت بود.

مهمترین اشکالی که استفاده از این روش داشت و داره ، مشکل با فایروال ها و اجبار برای رجیستر شدن کامپوننت ها در کلاینت هست. حتما بارها دیدید که در بعضی سایت ها از شما میخواد که یک activex رو نصب کنید تا سایت فعال بشه... شبیه همون مساله برای dcom هم هست

برای همین امروزه مرورگرهای مختلف با استفاده از پروتکل http/https براحتی و بدون دردسر شما رو به دنیای اینترنت وصل میکنند.

----------


## golbafan

یک مثال ساده برای استفاده از روش com/docm  (البته باز هم میگم ، توصیه نمیکنم از این روش قدیمی و پر دردسر استفاده کنید)

سمت سرور:
1- اول از همه یک vcl-application ایجاد میکنیم.
2- از منوی file\new\other استفاده میکنیم و یک remote data module رو ایجاد میکنیم:
1.jpg

3- در فرم بعدی یک نام برای کلاس مورد نظر انتخاب میکنیم (مثلا Tmytest)
2.jpg

4- در مرحله بعد میبینید که پروژه شما تکمیل شده است و برای کلاسهای ایجاد شده و خود پروژه یک سری guid ایجاد شده است:
3.jpg

5- سپس روی کلید رجیستر کلیک کنید تا نرم افزار سرور کامپایل و رجیستر بشه
4.jpg

6- بعدش برنامه رو اجرا میکنیم و میزاریم باز بمونه...

----------


## golbafan

تنظیمات ویندوز برای حالت DCOM

1- نرم افزار سرور باید رجیستر شده باشه و در حال اجرا باشه
2- باید سرویس های COMSysApp و MSDTC در حال اجرا باشند. در این وضعیت پروسس هایی طبق شکل زیر رو در تسک منیجیر خواهید دید:
5.jpg

3- نرم افزار مدیریت سرویسهای com رو باز کنید (Component Services) و روی MyComputer که در مسیر زیر قرار داره راست کلید کرده و گزینه properties رو بزنید:
  console_root/component_services/computers/MyComputer
6.jpg

 4- نام کامپیوتر شما در اینجا دیده میشه که باید یک جا یادداشت کنید. حالا به تب های مختلف سر میزنیم
در تب Default Properties باید گزینه اول یعنی enable distributed com on this computer تیک خورده باشه
در تب Default protocols برید و اگر پروتکل Connection-Oriented tcp/ip در لیست DCOM Protocols موجود نبود اضافه کنید و بعدش روی کلید properties بزنید
اینجا باید یک پورت دلخواه برای استفاده در کلاینتها تعریف کنید. 
7.jpg

5- تنظیمات ویندوز (بخش سرور) هم انجام شد

----------


## golbafan

نوشتن برنامه کلاینت برای حالت DCOM

1- یک پروژه جدید ایجاد کنید و طبق شکل کامپوننت های مربوطه رو بزارید
8.jpg

2- مشخصات ComputerName و ServerGUID رو طبق نام کامپیوتر خودتون و همچنین GUID نرم افزار سرور تنظیم کنید.
بجای ComputerName میتونید از IP هم استفاده کنید. فراموش نکنید باید هم در سرور و هم در کلاینت تنظیمات فایروال رو بررسی کنید

3- روی دکمه ای که در فرم قرار دادید دبل کلیک کرده و کد زیر رو بزنید.
procedure TForm1.Button1Click(Sender: TObject);
begin
  DCOMConnection1.Connected:=true;
end;

4- بعد از اجرای برنامه اتصال برقرار خواهد شد.

----------


## golbafan

سلام مجدد.
یکی از ساده ترین و کارامد ترین روشهای ارتباطی بین کلاینت و سرور در تکنولوژی دیتااسنپ برای نرم افزارهای متوسط روش TCP/IP و سوکت هست. بدلیل عدم استفاده این روش از سرویسهای مختلف سرورها و عمومیت آن، این روش سرعت بسیار بالایی داره. ولی این روش برای کار در اسکیل بالا یک مقدار اذیت خواهد کرد و امنیتش هم به اندازه زمانی که HTTP/HTTPS رو استفاده میکنیم نیست. بنابراین برای شبکه های اینترانت بسیار خوبه در حالی که برای کار در اینترنت یک سری ملاحضات داره که باید مورد توجه قرار بگیره.
برای کار در سطح اینترنت و بصورت جهانی، از سرویس هایی مثل IIS کمک میگیریم و امنیت رو با ssl تامین خواهیم کرد.

----------


## golbafan

سلام
امیدوارم در این مدتی که نبودم، حسابی با این تکنولوژی کار کرده باشید و مهارت های خودتون رو بالا برده باشید. 
احتمالا بعضی از شما الان خیلی بهتر از من به این روش مسلط شده اید که بسیار جای تبریک داره... :تشویق: 

همونطور که در پست قبلی گفتم استفده از پروتکل TCP/IP در دیتااسنپ خیلی راحته و در واقع حالت پیشفرض این تکنولوژی هست. ما اینجا فقط به یک IP و پورت نیاز داریم که پیامهای کلاینت و سرور رو بین همدیگه انتقال بدیم.
همونطور که میدونید سرور به ازای هر کلاینتی که بهش وصل میشه یک thread جداگانه ایجاد و کلیه موارد رو اونجا مدیریت میکنه...
سعی میکنم راههای امنیتی رو هم همراه با ایجاد یک پروژه با هم مرور کنیم... :چشمک: 

برنامه سرور رو اینجوری شروع میکنیم:
1- مثل قبل، اول از همه یک پروژه دیتا اسنپ سرور ایجاد میکنیم:
1.jpg

2-این بار حالت forms application / vcl رو امتحان میکنیم
2.jpg
3.jpg

3- برای اینکه با مقاله امنیت آشنا بشیم موارد Authentication و Encryption رو تیک میزنیم. دقت کنید که برای استفاده از Encryption باید OpenSSL رو در کلاینت و سرور نصب کنید!
4.jpg

4- یک پورت دلخواه انتخاب و تست میکنیم و برای نوع کلاس سرور هم مثل قبل حالت TDSServerModule رو انتخاب میکنیم
5.jpg
6.jpg

5- درنهایت پروژه رو ذخیره میکنیم...

----------


## golbafan

*کاستومایز کردن سرور*
وقتی  یک پروژه دیتا اسنپ مثل پست قبلی ایجاد میکنیم، کامپوننت DSServer1 که در  یونیت ServerContainerUnit1 ایجاد شده رو میبینیم که بصورت پیشفرض روی حالت  AutoStart قرار داره
من این پیشفرض رو برمیدارم تا مدیریت اتصال دست خودم باشه...
7.jpg

همینطور  میخوام برای کامپوننت DSAuthenticationManager1 که روی  ServerContainerUnit1 قرار داره یک تغییراتی در متد UserAuthenticate ایجاد  کنم که کلاینت ها مجبور بشن موقع اتصال به سرور نام کاربری و کلمه عبور  خودشون رو وارد کنن
به عنوان مثال در متد کد زیر رو مینویسم. (با این کد ساده، کلاینت ها موقعی میتونن به سرور وصل بشن که user=1 و password=1 رو استفاده کنن)
procedure TServerContainer1.DSAuthenticationManager1UserAuth  enticate
  (Sender: TObject; const Protocol, Context, User, Password: string;
  var valid: Boolean; UserRoles: TStrings);
begin
  { TODO : Validate the client user and password.
    If role-based authorization is needed, add role names to the UserRoles parameter }
  valid := (User = '1') and (Password = '1');
end;

حالا باید یک فکری برای مدیریت DSServer1 بکنیم... روی Form1 یک سری کامپوننت مثل زیر می چینیم:
8.jpg
بعدش هم کدهای زیر رو برای مدیریت DSServer1 میزنیم
procedure TForm1.Button1Click(Sender: TObject);
begin
  if ServerContainer1.DSServer1.Started = true then
    Exit;
  ServerContainer1.DSServer1.Start;
  Memo1.Lines.Add('Server Started on Port ' +
    ServerContainer1.DSTCPServerTransport1.Port.ToStri  ng);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  if ServerContainer1.DSServer1.Started = False then
    Exit;
  ServerContainer1.DSServer1.Stop;
  Memo1.Lines.Add('Server Stoped');
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Memo1.Clear;
end;

حالا برنامه سرور رو اجرا میکنیم...
9.jpg

----------


## golbafan

برای اینکه اتصال کلاینت ها رو مانیتور کنیم میتونیم رویدادهای OnConnect و OnDisconnect مربوط به DSServer1 رو هم ویرایش کنیم:

procedure TServerContainer1.DSServer1Connect(DSConnectEventO  bject
  : TDSConnectEventObject);
begin
  Form1.Memo1.Lines.Add(Format('%s : Client %s Connected From %s',
    [DateTimeToStr(Now), DSConnectEventObject.ChannelInfo.ClientInfo.Client  Port,
    DSConnectEventObject.ChannelInfo.ClientInfo.IpAddr  ess]));
end;

procedure TServerContainer1.DSServer1Disconnect(DSConnectEve  ntObject
  : TDSConnectEventObject);
begin
  Form1.Memo1.Lines.Add(Format('%s : Client %s Disonnected',
    [DateTimeToStr(Now), DSConnectEventObject.ChannelInfo.ClientInfo.
    ClientPort]));
end;

----------


## golbafan

حالا میتونیم بریم یک سری متد سرور ایجاد کنیم تا اونها رو در کلاینت بتونیم فراخوانی کنیم.
اگر به یونیت ServerMethodsUnit1 نگاه کنید میبینید که دو تا تابع به عنوان مثال اونجا اضافه شده *ما هم فعلا از همونها در کلاینت استفاده میکنیم*.
اگر بخواهیم میتونیم تابع دلخواه جدید اضافه کنیم ولی حتما دقت کنید که رفرنس این توابع باید حتما در بخش public از کلاس TServerMethods1 قرار بگیرند...

type
  TServerMethods1 = class(TDSServerModule)
  private
    { Private declarations }
  public
    { Public declarations }
    function EchoString(Value: string): string;
    function ReverseString(Value: string): string;
  end;

implementation

{$R *.dfm}

uses System.StrUtils;

function TServerMethods1.EchoString(Value: string): string;
begin
  Result := Value;
end;

function TServerMethods1.ReverseString(Value: string): string;
begin
  Result := System.StrUtils.ReverseString(Value);
end;

----------


## golbafan

*نوشتن کلاینت*
همونطور که قبلا اشاره کردم، برای کار با Encryption در دیتااسنپ باید حتما OpenSSL رو در کلاینت و سرور نصب کرده باشید. بسته به نوع سیستم عامل و همچنین نرم افزارهای سرور و کلاینت، باید ویرایشهای 32 یا 64 بیتی رو نصب کنید

نسخه 32 بیت https://indy.fulgan.com/SSL/openssl-...i386-win32.zip
نسخه 64 بیت https://indy.fulgan.com/SSL/openssl-...4_86-win64.zip

حالا برنامه کلاینت رو مینویسیم...

1- یک برنامه VCL Form معمولی درست کرده و ذخیرش کنید.

2- از منوی File\New\Other استفاده کنید و از شاخه Datasnap Server گزینه Datasnap Client Module رو انتخاب کنید
10.jpg

3- در پنجره ای که باز میشه Remout Server رو انتخاب کنید
11.jpg

4-در مرحله بعد گزینه اول رو انتخاب میکنیم
12.jpg

5- مرحله بعدی باز هم گزینه اول (TCP)
13.jpg

6- در مرحله بعد مشخصات سرور رو وارد میکنیم (یادتون باشه نرم افزار سرور باید در حال اجرا باشه و سرور استارت شده باشه)
14.jpg

دکمه تست رو بزنید و اگر مشکلی نباشه میتونید کار رو خاتمه بدید تا کلیه یونیت های لازم ایجاد بشن...
*(فایل های libeay32.dll و ssleay32.dll رو باید در پوشه سیستمی ویندوز کپی کرده باشید)*
15.jpg

حالا یونیت های ایجاد شده رو ذخیره میکنیم و در فرم اول برای تست نرم افزارهامون کدهای زیر رو میزنیم:
uses ClientModuleUnit1;

procedure TForm1.Button1Click(Sender: TObject);
begin
  label1.Caption:=ClientModule1.ServerMethods1Client  .ReverseString(Edit1.Text);
end;

16.jpg

----------


## golbafan

نرم افزارهای سرور و کلاینت مثال فوق رو که در پستهای 19 الی 23 توضیح دادم برای دانلود میزارم:

----------


## golbafan

*اتصال کلاینت و سرور با استفاده از پروتکلهای HTTP/HTTPS*

سلام
تا اینجا با پروتکلهای com و tcp/ip آشنا شدیم و برای هرکدوم مثالی گفته شد. در ادامه میخوایم اتصال کلاینت و سرور رو با استفاده از پروتکلهای اینترنتی بررسی کنیم و تفاوتهایی که داره رو بازگو کنیم...

----------


## Pascal

> *اتصال کلاینت و سرور با استفاده از پروتکلهای HTTP/HTTPS*
> 
> سلام
> تا اینجا با پروتکلهای com و tcp/ip آشنا شدیم و برای هرکدوم مثالی گفته شد. در ادامه میخوایم اتصال کلاینت و سرور رو با استفاده از پروتکلهای اینترنتی بررسی کنیم و تفاوتهایی که داره رو بازگو کنیم...


لطفا تاپیک را ادامه بدید

----------


## ParsaNM

کاش اين تاپيک ادامه پيدا ميکرد .
خيلي خوب توضيح ميدين جناب golbafan

----------


## masoode

خیلی عالی و جذاب بود  :تشویق:  :تشویق:  :تشویق:  حیف که نا تمام باقی مانده!!
 :گریه:

----------


## saeed_82

خیلی عالی بود چرا دیگه ادامه ندادید جناب گلبافان

----------

