# Native Code > برنامه نویسی در Delphi > توسعه نرم افزارهای تحت شبکه > سوال: مشکل با اتصال به datasnap

## soft-c

من برنامه را به وسیله datasnap نوشتم . الان برنامه ای که سمت کلاینت است به datasnap وصل نمیشه . ابتدا پیغام Error loading MIDAS.DLL را  می داد که dll مربوطه را دانلود و regist کردم . الان خطایی که میده این است :



> Access violation at address 0098FBCF in module 'PrjMapsa.exe'. Read of address 00000000


از طریق messgaebox برنامه را trace کردم :

sqlconnection.connected:=false; sqlconnection.connected:=true;
1
dsp1.connected:=false; dsp1.connected:=true;
2
cds.connected:=false ; cds.connected:=true;

تا قسمت 2 مشکلی نیست ولی در قسمتی که clientdataset می خواد اجرا بشه اون خطا را می ده .

----------


## Mask

رو اون سیستم میخواهید از کلاینت دیتاست استفاده کنید که مشکل پیش میاد.
برنامتون رو در چه ویندوزی ران میکنید؟

----------


## soft-c

> رو اون سیستم میخواهید از کلاینت دیتاست استفاده کنید که مشکل پیش میاد.


خوب مگر این راه مشکلی داره ؟ راه بهتری هم هست؟
ویندوز 7 و ویندوز 10

----------


## hp1361

سلام.
اگر کارهای مربوط به بانک اطلاعاتی رو قصد داری در برنامه ت انجام بدی، پیشنهاد من استفاده از TMS RemoteDB هستش.

راحت و ببی دردسر و البته Stable.

موفق باشیم

----------


## soft-c

> رو اون سیستم میخواهید از کلاینت دیتاست استفاده کنید که مشکل پیش میاد.
> برنامتون رو در چه ویندوزی ران میکنید؟


در سیستم خودم به خوبی کار می کنه ولی کلاینت را که روی یک سیستم دیگه می برم مشکل پیدا می کنه

----------


## ابوالفضل عباسی

خب ممکنه پورت مربوط به Datasnap بسته باشه.
درضمن اگر روی کلاینت ها انتی ویروس هست اون ها رو غیر فعال کن ببین مشکلت راه میوفته یا نه.

----------


## soft-c

> خب ممکنه پورت مربوط به Datasnap بسته باشه.
> درضمن اگر روی کلاینت ها انتی ویروس هست اون ها رو غیر فعال کن ببین مشکلت راه میوفته یا نه.


آنتی ویروس ها را غیر فعال کردم . پورتها را هم تغییر دادم . روی datasnap و در  servertransport مقدار port را از 211 به 57830 jyddv nhnl 
سمت کلاینت هم در sql connection و در قسمت driver مقدار پورت را به 5730 تغییر دادم . مقدار dsproxyport هم 8888 است ولی باز هم کار نکرد و هموم خطای قبلی را داد .

----------


## ابوالفضل عباسی

در sqlconnection قسمت driver رو datasnap بگذار.
و بعد params اش رو اجرا کن:
hostname رو localhost بکن.
DriverUnit رو Data.DbxDatasnap بکن.
و پورتش رو 211 بگذار.

و بعد DSRestConnection در بخش host رو localhost بکن.
و پورتش رو 8080 بگذار.
حالا با اعمال این تنظیمات یک تست بزن ببین چه اتفاقی میوفته.

----------


## soft-c

> در sqlconnection قسمت driver رو datasnap بگذار.
> و بعد params اش رو اجرا کن:
> hostname رو localhost بکن.
> DriverUnit رو Data.DbxDatasnap بکن.
> و پورتش رو 211 بگذار.
> 
> و بعد DSRestConnection در بخش host رو localhost بکن.
> و پورتش رو 8080 بگذار.
> حالا با اعمال این تنظیمات یک تست بزن ببین چه اتفاقی میوفته.


DSRestConnection  که وقتی تنظیمات را انجام دادم و test connection زدم خطا داد . (DSRestConnection   را در datasnap و در servercontainer اضافه کردم)
و یک سوال : اینطوری یعنی در شبکه هم کار می کند ؟ چون شما گفتی localhost در صورتیکه در شبکه فکر می کنم باید ip مربوط به سرور را وارد کنیم

----------


## ابوالفضل عباسی

من خودم با localhost کار میکنم و کلاینت هام هم درست کار میکنه.
دقیقا این loacalhost نمی دونم چرا در شبکه کار میکنه و نیاز به ip نداره. :متفکر:

----------


## soft-c

DSRestConnection  را درست قرار دادم ؟ به نظر شما چرا کار نمیکنه ؟ روی سیستم خودم کار می کنه . تست کردم دیدم پورت 211 هم باز هست .
localhost يا هاست محلي ،‌ براي شما كار سرور رو ميكنه منتها تو خود سيستم يا رايانتون
من یک بار روش کلی را توضیح می دم شاید جایی اشتباه کردم :
سمت datasnap:
روی servercontainer که یک dssserver و یک dssserverclass و یک dstcpservertransport قرار داره .
در servermethod هم که یک FDConnection گذاشتم و به sql وصلش کردم . برای هر جدول هم یک FDTAble و یک Datasetprovider گذاشتم . 

سمت کلاینت :
یک sqlconnection گذاشتم با همون تنظیماتی که گفتید و یک DSProviderconnection و یک clientdataset گذاشتم و فیلدهای جدول را در clientdataset اضافه کردم .(Add Fielads)

----------


## ابوالفضل عباسی

localhost روی سرور و کلاینت هست.
همه چیز و همه مراحل شما درسته،ولی من بجای FDTable از FDMemTable استفاده کردم و بقیه کار هاش مثل شما انجام شده. :متفکر:

----------


## soft-c

DSRestConnection  کجا باید قرار بگیره؟

----------


## BORHAN TEC

برای این کارها حتماً باید یک برنامه تست درست کنید که بتونیم برنامه رو خطایابی کنیم. پرسیدن این سوالها بدون نمونه پروژه بی جواب باقی میمونه. در ضمن در این شرایط حتی به فایل Midas.dll هم نیازی نیست و بجاش میتونید یونیت MidasLib رو به قسمت uses اضافه کنید.

----------


## ابوالفضل عباسی

DSRestConnection  فرق نمی کنه کجا باشه.
در برنامه من در صفحه main قرار داره

----------


## soft-c

> DSRestConnection  فرق نمی کنه کجا باشه.
> در برنامه من در صفحه main قرار داره


منظورم این است که سمت کلاینت باشه یا سمت datasnap

----------


## soft-c

MultiTierServerMapsa.rar
آقا این برنامه سمت datasnap  من است . منتهی دیگه جدول هاش را نفرستادم

----------


## soft-c

client.rar
این هم نمونه کد سمت کلاینت

----------


## ابوالفضل عباسی

باید در datasnap کلاینت باشه.
روی پروژه ات یه نگاه میکنم،تغییرات داخلش ایجاد میکنم برات میفرستم.

----------


## ابوالفضل عباسی

در sql connection در hostname بجای localhost باید ip سرور قرارداشته باشه.
موقعی که سرور و کلاینت روی یک دستگاه هستند از local host استفاده میشه.
برای من هم پروژه ات پیغام میداد،نتونستم با روشی که استفاده کردی درست کنم،برای همین از روش Firedac استفاده کردم و درست کرد(فقط 2 نکته):
1-همون طور که در بالا اشاره کردم sql connection رو ip سرور بده(در پروژه)
2- در کامپوننت FDTableAdapter(در پروژه اسمش رو TAMessage گذاشته ام)بخش DatSTableName رو من Table1 مقدار دهی کردم،در اینجا اسم بانکت که روی سرور هست رو باید بدهی.
حالا ببین درست کار میکنه یا نه.
sql connection رو متصل کن و روی button ای که Connect نوشته کلیک کن ببین پیغام میدهد یا نه(اگر پیغام داد یعنی مشکل داره)
Client.zip
درضمن:فایل سرورت باز نشد،unit هاش نبود.

----------


## soft-c

server.rar
این هم فایل کامل سرور




> برای من هم پروژه ات پیغام میداد،نتونستم با روشی که استفاده کردی درست کنم،برای همین از روش Firedac استفاده کردم و درست کرد


منظورتون از firedac چیه؟ من هم از firedac استفاده کردم

کامپوننت TFDStanstorageBinLink چیه ؟ خطا می گیره.

یونیت system.jason را هم خطا می گیره.

----------


## ابوالفضل عباسی

firedac مجموعه کامپوننت هایی هستند که میشه برای بانک اطلاعاتی مثل ado و هم برای datasnap استفاده کرد.
TFDStanstorageBinLink برای datasnap با استفاده از firedac هست و برای برنامه نویسی استفاده نمیشه و یک ارتباط ایجاد میکنه(link میکنه).
jason نداشت پروژه ام؟.
شاید از جاهایی ایراد میگیره که نمی تونه نشون بده.
سمت سرور هم مشکلی نداشت و درست بود،احتمالا بخش کلاینت ایراد داره.
این پروژه ای که گذاشتم نمونه datasnap سمت کلاینت از طریق کامپوننت های firedac هست،خودم برای datasnap از firedac استفاده میکنم نه clientdataset.

----------


## soft-c

> firedac مجموعه کامپوننت هایی هستند که میشه برای بانک اطلاعاتی مثل ado و هم برای datasnap استفاده کرد.
> TFDStanstorageBinLink برای datasnap با استفاده از firedac هست و برای برنامه نویسی استفاده نمیشه و یک ارتباط ایجاد میکنه(link میکنه).
> jason نداشت پروژه ام؟.
> شاید از جاهایی ایراد میگیره که نمی تونه نشون بده.
> سمت سرور هم مشکلی نداشت و درست بود،احتمالا بخش کلاینت ایراد داره.
> این پروژه ای که گذاشتم نمونه datasnap سمت کلاینت از طریق کامپوننت های firedac هست،خودم برای datasnap از firedac استفاده میکنم نه clientdataset.


TFDStanstorageBinLink را برای من خطا می گیره . چه کار باید بکنم . داخل کامپوننت های firedac هم نبود . البته من از xe5 استفاده می کنم

----------


## ابوالفضل عباسی

خب باید ورژن جدید firedac رو بگیری و نصب کنی،این ها مربوط به ورژن جدیده.

----------


## soft-c

> خب باید ورژن جدید firedac رو بگیری و نصب کنی،این ها مربوط به ورژن جدیده.


امکان به روز رسانی این کامپوننت هست؟ اگر میشه به روز کرد چه ورژنی را باید دانلود کد؟
یا باید کلا ورژن جدید دلفی را نصب کرد؟

----------


## ابوالفضل عباسی

فکر نکنم بشه بروزرسانی کرد.باید ورژن جدید firedac رو دانلود کنی و نصب کنی.(الان ورژن جدیدش رو نمیدونم چنده،ونیازی به تغییر ورژن دلفی نیست)
ورژنش برای هر نسخه از دلفی فرق میکنه،بخاطر همین نمی دونم ورژن چندش به دلفی xe5 میخوره.

----------


## soft-c

بالاخره مجبور شدم ویندوز را عوض کنم و دلفی xe8 را نصب کنم . ولی الان StreamGet را نمیشناسه . مربوط به چیه؟
 LMemStream := CopyStream(TServerMethods1Client(Server).StreamGet  );




> 2- در کامپوننت FDTableAdapter(در پروژه اسمش رو TAMessage گذاشته ام)بخش DatSTableName رو من Table1 مقدار دهی کردم،در اینجا اسم بانکت که روی سرور هست رو باید بدهی.
> حالا ببین درست کار میکنه یا نه.


منظورتون از بانکی که در سرور وجود دارد چیه؟ یعنی اسم دیتابیس که در sql server هست ؟ یا اسم table که در sql server هست ؟ یا منظورتون اسم کامپوننت FDTable هست که در سمت datasnap وجود دارد؟

----------


## ابوالفضل عباسی

اسم table که در sql server است.
بعد فکر کنم یونیت stream رو هم uses بکنید.

----------


## soft-c

> اسم table که در sql server است.
> بعد فکر کنم یونیت stream رو هم uses بکنید.


یک سوال : این طوری که شما می گید یعنی کلاینت داره عملا جدول را از دیتابیس مستقیما دریافت می کنه . پی مگر منطق کار نباید این طوری باشه که در سمت datasnap جدول ها لود بشه و کلاینت ها جداول را از datasnap دریافت کنند و به صورت مستقیم ارتباطی با دیتابیس نداشه باشند




> بعد فکر کنم یونیت stream رو هم uses بکنید.


همچین unit ای که نداره ولی چند تا در مورد stream بود اضافه کردم ولی یاز هم نمی شناخت.

----------


## ابوالفضل عباسی

نه جدول برای کلاینت ها لود میشه و تغییرات رو اعمال میکنند و بعد در جدول اصلی بارگذاری میشه.
Stream هم به صورت پیش فرض هست نیاز به uses  کردن نیست.ولی شما اگر system استفاده نشده این رو هم uses کنید.

----------


## soft-c

> نه جدول برای کلاینت ها لود میشه و تغییرات رو اعمال میکنند و بعد در جدول اصلی بارگذاری میشه.


پس چه تفائتی با روشی که جدول ها را در datasnap لود می کنیم و بعد کلاینت ها به datasnap متصل می شوند و جدول ها را میگیرند چیه؟ 
اصلا در این روش چه نیازی به datasnap هست؟



> Stream هم به صورت پیش فرض هست نیاز به uses کردن نیست.ولی شما اگر system استفاده نشده این رو هم uses کنید.


منظورم اینه که یونیتی به اسم stream نمیشناسه . یعنی وقتی  stream را use می کنم  خطا می گیرد که این یونیت ناشناخته است .

----------


## ابوالفضل عباسی

ببینید شاید منظور رو درست نرسونده باشم.
اصل datasnap اینکه بانک اصلی که در سرور است،با این روش برای کاربران موجود در شبکه محلی و یا wan باز میشه و کاربران انگار که پای سرور نشسته اند میتوانند روی جدول تغییراتی اعمال کنند بدون اینکه Send , receive انجام بشه.و موقعی که میخواستند اطلاعات رو نهایی بکنند و در بانک اصلی ذخیره بشه،datasnap تغییرات اعمال شده در جدول فرضی کاربر روی بانک اصلی اعمال میکنه.
حال اگر بعضی تغییرات تکراری باشه،میتونید فرمان بنویسید که با یک تغییر اندک در اطلاعات این تغییرات رو اعمال بکنه.اگر نه میتونید فرمان بنویسید که به کاربری که تغییرات تکراری اعمال کرده پیغام بدهد که اطلاعات رو اصلاح کنید.

مزیت datasnap اینکه یک بانک اصلی دارید و تعدادی کاربر به اون متصل میشوند تغییراتی اعمال میکنند.این طوری نیاز نیست بانک اطلاعاتی روی تک تک سیستم کاربران باشه.

امیدوارم مفهوم رو درست رسونده باشم.

در datasnap نمی شه یه جدول لود کرد و بقیه به اون جدول وصل بشن.با datasnap جدول اصلی بانک اطلاعاتی رو که روی یک سرور هست،در cache سیستم کاربر در قرار میگیره و تا زمانی که برنامه بسته نشده و دستگاه ریست نشود این بانک روی cache می مونه.تا زمانی که ثبت نهایی بشه.

یونیت stream پیش فرض دلفی هست و نیازی به uses کردن یونیت نیست،نمیدونم چرا برای شما ارور میدهد

----------


## hp1361

سلام

ما از Datasnap استفاده میکنیم تا یک برنامه Multi-Tierرو پیاده سازی کنیم. یک Tier دیتابیس، یک Tier برنامه سرور و یک Tier برنامه کلاینت.

برنامه سرور متدهایی رو ارائه میده که کلاینت های مختلف بر اساس نیازشون میتونند از اون استفاده کنند(یه چیزی شبیه وب سرویس در برنامه نویسی وب که فایل WSDL اطلاعاتی در خصوص وب سرویس ارائه میده).

برنامه کلاینت شما صرفاً قابلیت هایی رو میتونه انجام بده که برنامه سرور ارائه داده باشه. حالا برنامه سرور میتونه عملیات CRUD رو ارائه بده و یا چیزهای دیگه! این دیگه بر میگرده به منطق برنامه شما.

مثلا یه تابع داشته باشی که بر اساس یک پارامتر در بانک جستجو کنه و یک رکورد یا چندین رکورد رو برگردونه( بر اساس منطق پیاده سازی شما) و سایر عملیات

موفق باشیم

----------


## soft-c

چیزی که من برداشت کردم به این صورت است :
1- می توانیم جداول را در tier سرور لود کنیم و به کلاینت ها دسترسی بدهیم به tier سرور به جای tier دیتابیس .
2- کلاینت ها می توانند مستقیما جداول را از دیتابیس بگیرند و tier سرور می تونه فقط یک سری عملیات ها را انجام بده برای کنترل ارتباط کلاینت با دیتابیس .

اگر برداشت های من درست است کدام روش منطقی تر و بهتر است ؟




> حالا برنامه سرور میتونه عملیات CRUD رو ارائه بده


بیشتر توضیح می دید این قسمت را ؟

----------


## hp1361

سلام

CRUD همون چهار عمل اصلی روی بانکه. Read, Write, Update, Delete

آیا شما دارید از WebBroker  استفاده میکنید ؟

----------


## soft-c

> آیا شما دارید از WebBroker  استفاده میکنید ؟


خیر . چطور؟

----------


## soft-c

> LMemStream := CopyStream(TServerMethods1Client(Server).StreamGet  );


این تابع را در خود دلفی هم که جستجو کردم پیدا نکرد . حتی در اینترنت هم این تابع را پیدا نکردم . منظورم streamget است .

----------


## ابوالفضل عباسی

شما لطفا نمونه سورس های دلفی که در مورد datasnap هست رو ببینید،بعد از روی این برنامه الگو برداری کنید.
تازمانی که شما طرز کار این برنامه رو نبینید ما هرچه توضیح بدهیم فایده ای ندارد.
این Stream get رو نمی دونم چرا ایراد میگیره،روی سیستم های دیگه هم چک کردم و پیغام نمیداد
این stream get از توابع stream هست که دلفی پیش فرض به برنامه تون uses میکنه.

----------


## soft-c

> شما لطفا نمونه سورس های دلفی که در مورد datasnap هست رو ببینید،بعد از روی این برنامه الگو برداری کنید.
> تازمانی که شما طرز کار این برنامه رو نبینید ما هرچه توضیح بدهیم فایده ای ندارد.
> این Stream get رو نمی دونم چرا ایراد میگیره،روی سیستم های دیگه هم چک کردم و پیغام نمیداد
> این stream get از توابع stream هست که دلفی پیش فرض به برنامه تون uses میکنه.


دقیقا همین کار را می خواستم انجام بدم . ولی متاسفانه با مشکل تابع streamget برخورد کردم
دلفی که من نصب کردم xe8 است . حتی من در اینترنت هم که جستجو کردم این تابع وجود نداشت .

----------


## ابوالفضل عباسی

اگه موقع نصب xe8 تیک help رو برنداشته باشید،هنگام برخورد با این پیغام از help کمک بگیرید و ببینید help دلفی درمورد این تابع چی نوشته.

----------


## soft-c

> اگه موقع نصب xe8 تیک help رو برنداشته باشید،هنگام برخورد با این پیغام از help کمک بگیرید و ببینید help دلفی درمورد این تابع چی نوشته.


نه در help دلفی هم چیزی ننوشته . یعنی اصلا این تابع را نداره

----------


## ابوالفضل عباسی

ببخشید
دیگه هیچ راهکاری به ذهنم نمی رسه،خیلی عجیبه که داره از تابع پیشفرض دلفی ارور میگیره. :متفکر:

----------


## soft-c

> ببخشید
> دیگه هیچ راهکاری به ذهنم نمی رسه،خیلی عجیبه که داره از تابع پیشفرض دلفی ارور میگیره.


به نظرتون این تابع را خود کاربر در سمت سرور ننوشته ؟ به خاطر این قسمتش می گم : 
_TServerMethods1Client(Server).StreamGet_

چون من در اینترنت هم که گشتم همچین تابعی را نداشت .

----------


## ابوالفضل عباسی

نه
چون بخش مهم گرفتن get table هستش و نیاز به stream داره.
از اینترنت نمونه datasnap رو دانلود کنید و الگو برداری کنید.شاید در بقیه از این تابع استفاده نشده باشه.

----------


## soft-c

این پروژه را یک نگاهی می اندازید :
https://sourceforge.net/p/radstudiod...aSnap/FireDAC/

هنگامی که اجرا می کنم یعنی get table را می زنم این خطا را می ده :



> invalid binary storage format


البته اینجا هم تابع StreamGet را داره منتها همانطور که گفتم یک تابع است که خودش در سمت سرور تعریف کرده است .

----------


## ابوالفضل عباسی

نه این پروژه مشکلی نداشت.
و موقع get table به من پیغام access violation میداد که بخاطر اتصال بود،به من همچین پیغامی نداد. :متفکر:

----------


## soft-c

> نه این پروژه مشکلی نداشت.
> و موقع get table به من پیغام access violation میداد که بخاطر اتصال بود،به من همچین پیغامی نداد.


اگر اشتباه نکنم این برنامه از دیتابیس غیر از sql server استفاده کرده . آیا شما هم از همون دیتابیس استفاده کردید ؟

----------


## ابوالفضل عباسی

بله از همون دیتابیس.
با SQL تاحالا تست نکرده بودم ،اخیرا تست کردم ولی مشکلی نداشت.به بانک مربوط نمیشه.

----------

