همه
شما دفعات زيادي با صفحات وبي برخورد كردهايد، كه در آنها هنگامي كه
مقدار يرا از فيلد پائين افتادني (Drop dawn box) انتخاب ميكنيد، همه
صفحه از ابتدا refresh ميشود تا مثلاً اطلاعات يك (Drop dawn box) ديگر
استخراج شود. مثلاً شما از ليست كشورها، كشوري را انتخاب ميكنيد و سپس
صفحه post back ميشود تا ليست شهرهاي كشوري كه انتخاب كرديد در (Drop
dawn box) ديگري ريخته شود.
چون صفحه دوباره refresh ميشود، اينكار بسيار ناهنجار و باعث كندي
شديد عمليات در صفحه وب و باعث خستگي و انصراف كاربر ميشود چون ممكن است
حتي شما چندين (Drop dawn box) وابسته به هم داشته باشيد.
يكي از
راهحلهاي اين مشكل اينست كه شما همه انتخاب هاي ممكن را به همراه صفحه و
يا در يك آرايه جا و اسكريپت به همراه صفحه به كار بفرستيد، اما زماني كه
داده ها زياد باشند اين روش بيفايده و غير كارآمد است.
براي حل اين
مشكل Remote scripting انتخاب بسيار مهمتري است. به جاي اينكه شما همه
صفحه را refresh كنيد، كافيست در پس زمينه يك درخواست مخفي از ديد كاربر
به سرور فرستاده كه يك متد را اجرا كند و فقط اطلاعات مورد نياز را با
توجه به انتخاب كاربر تغير دهد و يا انتقال دهد. نتيجه كار بسيار بهتر و
دلچسبتر از قبل خواهد بود. در حقيقت Remote scripting مزاياي زيادي را
نسبت به مدل قديمي برنامههاي وب كه سنگين و كند بودند، فراهم كرده است و
ما با آن مي توانيم تنها يك كنترل مجزا را refresh كنيم و يا validate
(تعيين اعتبار) كنيم و يا حتي يك فرم را بدون اينكه مجبور باشيم تمام صفحه
را به سرور پست كنيم و مجدداً دريافت كنيم، پردازش كنيم. اين تكنيك بسيار
خوبي است كه خوشبختانه اكثر مرورگرهاي معروف و اصلي از آن پشتيباني
ميكنند.
در جريان سالهاي اخير من 2 پياده سازي معروف Remote
scripting را ديدهام. برگرديم به گذشته، هنگامي كه visual studio 6 به
بازار آمد، مايكروسافت فايلهاي سمت سرور و کلاینت را براي استفاده در يك
پوشه به نام Script library آماده كرده بود كه من از آن ديدم اين بود كه
از اپلتهاي جاوا براي ارتباط برقرار كردن بين کلاینت و سرور استفاده
ميكرد و براي همين ذاتاً كند بود. بنابراين من از Jsp استفاده كردم و يك
انتخاب بهتر پيدا كردم كه JSRS نام داشت. برحسب نوع مرورگر وب، JSRS يك شي
مخفي در صفحات ايجاد ميكرد كه درخواستها را به سرور ارسال ميكرد و سپس
پاسخها را دريافت ميكرد. JSRS بسيار كارآمدتر بود، اما فقط امكان
برقراري ارتباط به صورت غير همزمان (Asynchronous) ميسر ميساخت.
اكنون
با ASP.NET ، دوباره مجبور شدم كه از Remote scripting استفاده كنم. ابتدا
من يك كلاس كوچك با C# نوشتم كه از کلاینتهاي اسكريپتهاي مايكروسافتي و
JSRS اين پشتيباني ميكرد. اما بعد تصميم گرفتم يك پياده سازي سمت کلاینت
بهتر بجز نوع مايكرو سافتي و JSRS اين بسازم. من يك راهحل تركيبي بر
مبناي 2 نوع قبلي انتخاب كردم كه به نظرم بهتر از آنها بود. كد نمونه:
يك فايل نمونه قابل Down Loud به نام rsDemo.aspx كه به صورت كامل همه مطالب را پوشش ميدهد در آدرس زير موجود است.
Demo Page
پياده سازي كاربردي:
من
سعي ميكنم كه پياده سازي Remote scripting خودم تا حد ممكن به صورت ساده
و راحت باشد. تنها چند مرحله ساده در سمت سرور و نيز کلاینت بايد انجام
دهيد. براي درك بهتر مطالب ميتوانيد از فايل rsDemo.aspx استفاده كنيد. سمت کلاینت
1 – فايل rs.js را در صفحه aspx خود Include كنيد (شبيه زير):
1. <script language="JavaScript" src=/scripts/rs.js></script>
2 – از Rs. Execute براي اجراي Remote Method خود استفاده كنيد. (شبيه شكل زير):
1. function dro_pdown_onchange()
2. {
3. RS.Execute("page.aspx", "RemoteMethod",
4. "optionalParam1", "optionalParam2", ....,
5. callback, optionalErrorCallback,
6. optionalCallbackParam2, optionalCallbackParam3,
7. optionalCallbackParam4)
8. }
صفحه
pag.aspx جايي است كه Remote Method را در آن خواهيد نوشت و هنگام
فراخواني از سمت کلاینت در سمت سرور اجرا ميشود. پارامترهاي Remote
Method اختياري هستند، بنابراين اگر نيازي به آنها نداريد ميتوانيد متد
را بدون آنها صدا بزنيد. تابع call back (كه يك پارامتر رشته اين نيست)
نيز اختياري است و اگر استفاده شود، هنگامي كه سرور پاسخ ميدهد اين تابع
اجرا ميشود. بنابراين براي پردازش و يا عملي پس از پاسخ سرور مثلاً نمايش
اطلاعات بايد تابع call back را به عنوان پارامتر استفاده كنيد.
اولين
پارامتر مقدار برگشتي توسط Remote Method خواهد بود كه در واقع پاسخ سرور
است كه به رشته تبديل شده است. اگر خطايي روي دهد، شما ميتوانيد تابع
call back ديگري را به عنوان پارامتر به تابع ارسال كنيد كه اطلاعات خطاي
روي داده را دريافت و پردازش و در صورت نياز عملي انجام دهد.
اگر اين پارامتر (تابع خطا) ارسال نشود به صورت پيش فرض يك پيغام بر حسب نوع خطا نمايش داده ميشود.
در
صورتي كه شما optional call back param 2 و optional call back param 3 و
optional call back param 4 را به متر ارسال نمائيد، آنها نيز به تابع
call back برگردانده ميشوند.
فراموش نكنيد كه متد Rs. Execute به صورت
نامتقارن (ناهمزمان) است و بنابراين call back ها تنها راه فهميدن اين
است كه چگونه و كي پاسخ خواهد داد.
3 – در صورتي كه شما نياز به پاسخ
سرور (پاسخ Remote Method) داريد يك تابع call back به متد فوق ارسال
نمائيد و به صورت اختياري براي خطاها ميتوانيد چنين كاري را انجام دهيد. 1. function callback(result)
2. {
3. alert("The remote method returned this: " + result)
4. }
5.
6. function errorCallback(result)
7. {
8. alert("An error occurred while invoking the remote method: " + result)
9. }
سمت سرور:
1 – مطمئن شويد كه فايل AMS.Web.Remotescriptin.dll در پوشه bin وب سايت شما قرار دارد.
2 – در ابتداي رويداد page-Load در صفحه وب خود دو خط پائين را اضافه كنيد:
1. if (AMS.Web.RemoteScripting.InvokeMethod(Page))
2. return
اينكار
باعث انجام شدن چندين عمل ميشود. اولاً بررسي ميكند كه درخواست مربوط به
Remote Method کلاینت در صفحه است، در صورتي كه درخواست Remote Method
نباشد، false برميگرداند و در صورتي كه درخواست کلاینت باشد Remote
Method اجرا خواهد شد و بلافاصله پاسخ به کلاینت برگشت داده خواهد شد.
در
صورتي كه صفحه شما متد page-load ندارد (و شما نميخواهيد داشته باشيد)
ميتوانيد اين دو خط را در بين دو تگ <% %> در بالاي صفحه page.aspx
بنويسيد.
3- Remote Method خود را به صورت public و يا عنصر static به كلاس صفحه خود اضافه كنيد:
1. public string RemoteMethod(string param1, string param2, ... )
2. {
3. return "This is what the client sent me: \n" + param1
4. + "\n" + param2 + ...
5. }
در صورتي كه شما به خواندن مقدار يك فيلد نياز داريد، ميتوانيد از يك صفت (property) بجاي متد مانند زير استفاده نمائيد:
1. public string RemoteProperty
2. {
3. get { return m_someField }
4. }
نيازي نيست نوع مقدار برگشتي string باشد، اما قبل از ارسال به کلاینت به صورت رشته تبديل ميشود و بعد ارسال مي گردد.
همه
پارامترها بايد از نوع رشته و متدها (يا صفتها property ها) بايد public
باشند و در غير اين صورت شما خطاي System-Missing Method Exception را
دريافت مي كنيد.
به عنوان يك روش ديگر براي اجراي Remote Method يك متد
يا صفت (property) public در صفحه، شما ميتوانيد به صورت مستقيم متد
public و يا property يك كنترل را در صفحه اجرا كنيد. براي مثال اگر شما
مي خواهيد صفت Text يك Textbox به نام txt Amount را استفاده كنيد، مقدار
"txtAmount" را به عنوان Remote Method به تابع Rs. Execute ارسال كنيد. نكات:
من يك متد به نام Replace option در فايل rs.js
اضافه كردم كه به راحتي نتايج يك Remote Method را در يك Dropdown box
ميريزد. در واقع راه حلي است براي مشكلي كه در اول مقاله به آن اشاره
كردم (ليست كشورها) اين متد حاصل نتيجه به صورت رشته با فرمت اين مانند
زير است: "<option value=0>Text 0</option><option selec_ted value=1>Text 1</option>..."
شما ميتوانيد از آن در يك call back مانند مثال زير استفاده كنيد:
function callback(result)
{
RS.ReplaceOptions(document.form.theDropDown, result)
}
و
حتي روش جايگزين بهتر اينكه Rs.Replace option 2 است كه ميتوان به صورت
مستقيم آن را به عنوان call back به متد Rs. Execute ارسال كرد. مانند
زير: function dro_pdown_onchange()
{
RS.Execute("page.aspx", "RemoteMethod",
"optionalParam1", "optionalParam2", ....,
RS.ReplaceOptions2, document.form.theDropDown)
}
Rs.Replace
option 2 همان پارامترهاي مشابه Rs.Replace option ميگيرد، اما به صورت
عكس به اين معني كه به عنوان يك call back استفاده ميشود. اين كار به شما
اين امكان رامي دهد كه در يك درخواست هر كاري را انجام دهيد.
شي RS
همچنين عضوي به نام debug دارد كه شما ميتوانيد آن را با True مقدار دهي
كنيد (Rs.debug = True) اطلاعات خطايابي پشت صحنه استفاده شده در ارتباط
با سرور به شما نشان داده ميشود.
در سمت سرور، شما كلاسي به نام
Remote scripting خواهيد ديد كه هر سه حالت ممكن کلاینتها يعني: RS باشد
يا JSRS يا نوع مايكروسافتي (MSRS) كه در ابتدا توضيح دادم را پشتيباني
ميكند و با آنها كار ميكند.
نوع کلاینت بر اساس پارامترهاي ارسال شده
در درخواست تعيين ميشود. اگر شما پياده سازي کلاینت مخصوص خودتان را
داريد، معماري اين تكنيك اين امكان را با deriving (اشتقاق) كردن كلاس
Remote Scripting Client به شما ميدهد، كه کلاینت مخصوص خودتان را نيز در
سمت سرور به راحتي پشتيباني كند.
نوع مايكرو سافت اين تنها پياده سازي
سمت کلاینت است كه از درخواست همزمان (synchronous) به سرور، پشتيباني
ميكند. بنابراين اگر شما مطلقاً به اين امكان نياز داريد، بايد از کلاینت
نوع مايكروسافتي استفاده كنيد.
همه چيزي كه شما نياز داريد فايل هاي
rs.html و Rs.proxy.calss از پوشه script library است. من شخصاً توصيه
نميكنم از اين روش استفاده كنيد چون مرورگر تا دريافت پاسخ سرور متوقف
ميماند و با روش سنتي تفاوتي ندارد و همچنين مرورگر نيز بايد از جاوا
پشتيباني كند. با اين حال من پشتيباني از آن را به كلاس Remote Scripting
Client اضافه كردم.
نكته پاياني براي اتمام مقاله اينكه، براي dro_p
down هايي كه توسط درخواستهاي Remote Scripting مقدار دهي ميشوند، من
توصيه ميكنم view state آنها را توسط صفت (Enable view stat = false) غير
فعال كنيد. زيرا در هر بار فراخواني اطلاعات زيادي كه كاربرد مجدد ندارد
در هر درخواست انتقال مييابد و پهناي باند مصرف و سرعت كاهش پيدا ميكند.
اميدوارم اين مقاله بتواند به شما كمك كند.
دانلود کد برنامه