وب سرويسها سيستمي بسيار ساده دارند و از آنها ميتوان به عنوان ابزاري جهت برقراري ارتباط بين سيستمهاي با Platformهاي مختلف استفاده کرد، ولي با تمام قابليتها و امکاناتي که وبسرويسها دارند اين تکنولوژي در برخي موارد به اندازه کافي انعطافپذير و سريع نيست و لذا پاسخگوي گروه خاصي از نيازها نيست.
همانگونه که ميدانيد وبسرويسها امکاني جهت دسترسي به اشياء و توابع از طريق شبکه را فراهم ميکنند وب سرويسها سيستمي بسيار ساده دارند و از آنها ميتوان به عنوان ابزاري جهت برقراري ارتباط بين سيستمهاي با Platformهاي مختلف استفاده کرد، ولي با تمام قابليتها و امکاناتي که وبسرويسها دارند اين تکنولوژي در برخي موارد به اندازه کافي انعطافپذير و سريع نيست و لذا پاسخگوي گروه خاصي از نيازها نيست. بزرگترين عاملي که اين محدوديت را ايجاد ميکند نياز وب سرويسها به IIS و يا به عبارت ديگر ASP.NET runtime ميباشد. جهت فائقآمدن به اين مسايل ميتوان از Dot NET Remoting استفاده کرد. در واقع Dot NET Remoting هم دقيقاً همان سرويسي را فراهم ميکند که وب سرويسها فراهم ميکنند ولي داراي ويژگيهاي خاصي ميباشد که انعطاف و سرعت زيادي نسبت به وب سرويسهاي عادي فراهم ميکند. ?مقدمه
بهطور کلي اگر ساختار يک وب سرويس، (منظور از وب سرويس در اينجا NET ASP . وبسرويس ميباشد) را بررسي کنيم همواره دو جزء در ساختار آن وجود دارد: جزء اول همان کلاسهايي ميباشد که درست ميکنيد. به عبارت ديگر در داخل اين کلاسها منطقکاري وبسرويس و توابع عمومي و خصوصي وب سرويس قرار ميگيرند و پس از کامپايل، اين کلاسها به يک dll تبديل ميشوند. جزء بعدي يک وب سرويس که همواره موردنياز ميباشد برنامهاي است که به يک پورت سيستم گوش ميدهد و درخواستهاي کلاينتها را ميگيرد و به جزء اول ميدهد و پس از پردازش پاسخ را گرفته و به کلاينت ارسال ميکند. در توليد وبسرويسهاي عادي تقريباً تمام تمرکز روي جزء اول يعني کلاسهاي آن است. جزء بعدي همان IIS است که کافي است در برخي موارد تنظيمات خاصي روي آن انجام دهيم. با استفاده از NET Remoting. سيستمهايي جهت دسترسي از طريق شبکه فراهم خواهيم کرد که در واقع دو بخش يک وب سرويس در آنها هم وجود دارد، ولي اينبار ميتوانيم ازIIS استفاده نکنيم و خودمان برنامه ميزبان (منظور برنامهاي که به شبکه گوش ميدهد و تبادل اطلاعاتي بين کلاينتها و کلاسهاي ما را فراهم ميکند) را بنويسيم. با اين توصيف در واقع ميتوان گفت که ASP.NET Web Serviceها نوع سادهشدهاي از سيستمهايي هستند که توسط NET Remoting. ميتوان توليد کرد چرا که در استفاده از ASP.NETWeb Serviceها مجبور به استفاده از IIS به عنوان برنامه ميزبان هستيم. قبل از اينکه شروع به پيادهسازي يک نمونه کامل نماييم، با يک ديد کلي اجزاء سيستم پيادهسازي شده توسط NET Remoting را مورد بررسي قرار ميدهيم.
?کلاسها
در سمت سرور، remote object همان کلاسهايي ميباشند که منطق اصلي کاري را تشکيل ميدهند. اين کلاسها به صورت يک dll روي سرور قرار ميگيرند و توابع public اين کلاسها هستند که در نهايت از طريق کلاينتها فراخواني شده و مورد استفاده قرار ميگيرند. Formatter کلاسي است که پاسخهاي سرور (مقادير ارسالي از remote object) را که به صورت يک سري اشياء ميباشند را گرفته و با کدبندي خاصي به يک سري از بايتها تبديل ميکند که مناسب جهت ارسال از طريق شبکه ميباشد. همچنين درخواستهايي را هم که کلاينت ارسال ميکند از کدبندي خاص آن خارج کرده و تبديل به يک شيء ميکند که قابلفهم براي remote object ميباشد. سمت کلاينت نيزformatter دقيقاً همين کار را انجام ميدهد ولي جهت عکس. به عمليات تبديل يک شيء به فرمتي قابلارسال و يا نگهداري که توسط Formatter انجام ميشود Serialize و به عکس اين عمل Deserialize ميگويند. Channel هاي سمت کلاينت و سرور پروتکل ارتباطي بين کلاينت و سرور و تنظيمات مربوط به آن را تعيين ميکنند. اينها در واقع همان برنامه ميزبان هستند که در سمت سرور در حالت Listening قرار دارد و در سمت کلاينت به صورت کلاينت ميباشند. اما کلاس Proxy که فقط در سمت کلاينت وجود دارد کلاسي است که دقيقاً مانند کلاسهاي داخل remote object ميباشد. کلاينت قادر به فراخواني توابع remote object به صورت مستقيم و بيواسطه نيست چرا که remote object روي سيستم ديگري در شبکه قرار دارد و لذا کلاسي تحت عنوان کلي Proxy با همان توابع Public که remote object فراهم ميکند در سمت کلاينت ايجاد ميشود که از ديد کلاينت همانند ساير کلاسهاي عادي ميباشد؛ ولي وقتي کلاينت تابعي از اين کلاس را فراخواني ميکند اين تابع يک پيام جهت فراخواني تابع مشابه خود درremote object ايجاد کرده و ارسال ميکند و پس از دريافت پاسخ، نتيجه را در اختيار کلاينت قرار ميدهد. توجه داشته باشيد که تمام اين کلاسها به طور کامل در اختيار شما ميباشند و شما ميتوانيد هر تغيير منطقي موردنياز را در هر کدام از اين کلاسها اعمال کنيد و اين همان انعطافپذيري کاملي ميباشد که NET Remoting . در اختيار شما قرار ميدهد. البته توليد تمام اين کلاسها احتمالاً براي برخي زياد هم خوشايند نخواهد بود. چرا که قطعاً زمان زيادي صرف توليد و اشکالزدايي آنها ميشود. جهت رفع اين مشکل ميتوانيد از NET. کمک بگيريد چرا که اگر نيازي به قابليتهاي خاص در اين سا ختار نداريد. داتنت تمام اين کلاسها را با رفتار عادي آنها براي شما توليد ميکند؛ مگر دو کلاس که ميبايستي شما آنها را توليد کنيد. همانطور که حدس زديد يکي کلاس remote object ميباشد که رفتار اصلي سيستم شما و قابليتهايي که ميخواهيد ارايه دهيد در اين کلاس قرار دارد و ديگري برنامه يا کلاس ميزبان ميباشد که قسمت channel را فراهم ميکند. در بيشتر موارد هدف استفاده از NET Remoting . بينياز شدن از IIS يا ASP.NET Runtime ميباشد. در ادامه مثال کاملي که در آن به جاي IIS از يک برنامه console استفاده ميشود را بررسي ميکنيم. بهعبارت ديگر برنامه ميزبان يک console Application ميباشد. در مثال ارايه شده برنامه کلاينت و سرور به صورت console ميباشند تا ضمن حفظ سادگي، رفتار دقيق کلاينت و سرور قابل مشاهده باشد. بديهي است در صورت تمايل ميتوانيد با انجام چند تغيير جزيي آنها را به برنامههاي windows form تبديل کنيد. در ادامه راهنماييهايي هم جهت اين تبديل آورده شده است. (کدهاي آماده مثال را ميتوانيد از سايت ماهنامه شبکه دانلود کنيد).
?يک مثال
به مثال زير توجه کنيد. همانطور که اشاره شد Remote Object کلاس يا کلاسهايي است که منطق اصلي موردنظر سيستم در آن قرار دارد. در اينجا يک کتابخانه ساده (dll) يا يک تابع عمومي را به عنوان remote object پيادهسازي ميکنيم. همانطور که ملاحظه ميکنيد از توابع console استفاده شده تا پيامهاي مناسبي هنگام فراخواني سازنده کلاس و يا تابع Hello در خروجي command Prompt چاپ شود. براي توليد اين remote object ميتوانيد يک پروژه از نوع classlibrary درNET. ايجاد کرده و کد مربوط را در کلاسي که به صورت پيشفرضNET . در پروژه ايجاد ميکند بنويسيد و يا ميتوانيد کد را در يک فايل متني ساده تايپ کنيد و با پسوند.cs ذخيره کنيد و با استفاده از دستور زير آن را کامپايل کنيد: .Csc/t:library/out:My Remote object
dll My Remote object.cs
توجه داشته باشيد که remote object از اين کلاس ارثبري کند (کلاس Marshal By Refobject قابليتهاي خاصي به کلاسي که از او ارثبري کند ميدهد تا آن کلاس جهت ارايه سرويسهاي ماندگار در حافظه (lifetime) بهينه شود).
using System;
using System.Runtime.Remoting;
namespace Client
class Client
static void Main(string[] args)
RemotingConfiguration.Configure("Client.exe.config");
MyRemoteObject.MyRemoteObject obj=new MyRemoteObject.MyRemoteObject();
Console.WriteLine(obj.Hello());
Console.ReadLine();
Remote Server
قسمت بعدي پيادهسازي remote server و به عبارت ديگر، برنامه ميزبان ميباشد، برنامه ميزبان و remote object را ميتوانيد در يک فايل يا اسمبلي پيادهسازي کنيد، ولي استفاده از دو فايل متفاوت قابليت استفاده مجدد (reuse ability) سيستم را بالا ميبرد. وظيفه برنامه ميزبان، درست کردن يک کانال ارتباطي و گوش دادن به يک پورت سيستم ميباشد تا به اين وسيله درخواستهاي کلاينتها را گرفته و به remote object بدهد. کانال ارتباطي remote server يا برنامه ميزبان را ميتوان با استفاده از فايل پيکربندي و يا با استفاده از برنامهنويسي تنظيم نمود که هر کدام معايب و مزاياي خاصي دارد. وقتي که از فايل پيکربندي (configuration file) استفاده ميشود، کدنويسي لازم در برنامه ميزبان به حداقل ميرسد و همچنين جهت تعويض تنظيمات کانال (به عنوان مثال شماره پورت، يا پروتکل و يا ...) نيازي به دستکاري کدبرنامه و کامپايل مجدد آن نداريد، بلکه فقط کافياست تنظيمات موردنظر را در فايل پيکربندي انجام دهيد. فايل پيکربندي فايلي است با فرمت XML که اطلاعات کانال را در آن قرار ميدهند. برنامه ميزبان هنگام اجرا، اطلاعات فايل پيکربندي را خوانده و با توجه به تنظيماتي که در آن ثبت شده، کانال ارتباطي را ايجاد ميکند، البته در صورتي که از فايل پيکربندي استفاده نکنيد نيز مزيت خاصي خواهيد داشت و آن تغيير دادن تنظيمات کانال در زمان اجرا توسط برنامه ميباشد. در اينجا جهت توليد برنامه ميزبان از فايل پيکربندي استفاده خواهيم کرد. اسم فايل پيکربندي را همنام با فايل اجرايي برنامه ميزبان بگذاريد با پسوند config. در اين صورت نام فايل Simpleserver.config خواهد شد. کدهاي داخل اين فايل به صورت زير ميباشند.
<configuration>
<system.runtime.remoting>
<application name="Client">
<client url="tcp://localhost:9000/Server">
<wellknown
type="MyRemoteObject.MyRemoteObject, MyRemoteObject"
url="tcp://localhost:9000/MyRemoteObject"/>
</client>
<channels>
<channel ref="tcp client" />
</channels>
</application>
</system.runtime.remoting>
</configuration>
همانطور که ملاحظه ميکنيد اطلاعات کانال و remote object در داخل عنصرsystem.runtime.remoting قرار دارد. عنصر application در فيلد name ، نام سرور را مشخص ميکند و در داخل عنصر service مشخصات remote object قرار دارد دو فيلد wellknown و mode مربوط به دستهبندي remote objectها ميباشد که در ادامه دستهبندي و انواع مختلف remote objectها را توضيح خواهم داد. فعلاً اين دو فيلد را همينگونه بپذيريد. در فيلد type مشخص ميشود که اين سرويس مربوط به کدام remote object ميباشد. در اين فيلد به زيرساخت NET Remoting. گفته ميشود که در کدام اسمبلي و در چه کلاس و namespaceاي در آن اسمبلي remote object قرار دارد. اگر به فايل توجه کنيد، مقدار رشتهاي فيلد type با کاما (,) دو قسمت شده است قسمت اول namespace و کلاس مربوط به remote object را مشخص ميکند و قسمت دوم نام اسمبلي مربوط به remote object را. (درNET. کدهاي نوشته شده در بستههاي خاصي به نام assembly بستهبندي ميشوند. هر اسمبلي دستوراتي به زبان IL و يک سري metadata دارد که NET runtime. با استفاده از اين اطلاعات آن را اجرا ميکند. توجه داشته باشيد که يک اسمبلي ميتواند در چند فايل باشد و يا برعکس چند اسمبلي در يک فايل. در اينجا اسمبلي remote object ما در در داخل يک فايل همنام با اسمبلي آن قرار دارد.) در فيلد Object Url آدرسي را مشخص ميکنيم که قرار است کلاينتها جهت دسترسي به remote object اين آدرس را بدهند. بعداً در فايل پيکربندي برنامه کلاينت خواهيد ديد که فيلدي با نام Url وجود دارد که آدرس remote object را در آن خواهيم نوشت. در اين آدرس پس از مشخص کردن پروتکل و IP آدرس کامپيوتري که برنامه ميزبان در آن قرار دارد، مقداري که به فيلد Object Url دادهايم را در آن قرار خواهيم داد. فيلد Object Url ميتواند يک URL کامل باشد بدين صورت که remote object در روي سيستم ديگري در وب قرار دارد و يا حتي remote object خود يک وب سرويس ميباشد. در اينجا به اين فيلد فقط نام اسمبلي remote object را ميدهيم و کلاينت هم در فايل پيکربندي خود در فيلد Url از همين نام استفاده خواهد کرد. اگر دقت کرده باشيد، متوجه شدهايد که مشخصات remote object در داخل عنصر قرار گرفته است. در واقع جالب است بدانيد که در داخل عنصر<>service به هر تعداد remote object و يا به عبارت ديگر سرويس که بخواهيم ميتوانيم معرفي کنيم؛ به شرط اينکه به هر کدام از آنها کانال خاصي اختصاص دهيم و بهطور کلي از عهده مديريت چنين سيستمي برآييم. در چنين حالتي يک برنامه ميزبان درخواستهاي استفاده از چندين remote object را گرفته و handel ميکند. عنصر channels تنظيمات مربوط به کانال يا کانالهاي ارتباطي را در خود دارد. در اينجا فقط از يک کانال استفاده خواهيم کرد و به جاي ايجاد کانال جديد، از کانالهاي تعريفشده در Machine.config استفاده ميکنيم. جهت اينکار از فيلد channel ref و سپس ازid کانال تعريف شده در machine.config استفاده ميکنيم. فيلد port هم شماره پورتي که برنامه ميزبان به آن گوش خواهد داد را مشخص ميکند. فايل machine.config فايل XMLاي است که تنظيمات ويژهاي در سطح سيستم در آن قرار دارد، از جمله کانالهايي که به صورت پيشفرض در آن تعريف شدهاند اين فايل در مسير Microsoft.NET Frameuork CONFIG درSystem Root قرار دارد. با ديدن قسمتي که در آن کانال tcp client تعريف شده است، متوجه ميشويد که تعريف کانال جديد در فايل پيکربندي برنامه ميزبان کار چندان دشواري نيست. ضمناً علاوه براين کانال پنج کانال ديگر نيز در اين فايل تعريف شدهاند که از کانال tcp client در پيادهسازي برنامه کلاينت استفاده خواهيم کرد. با وجود فايل پيکربندي، تمام کاري که برنامه ميزبان بايد انجام دهد، خواندن محتويات فايل پيکربندي و ايجاد کانال و قرار دادن آن در حالت listining جهت دريافت درخواستهاي کلاينتها ميباشد. براي انجام تمام اين کارها کافياست يک تابع static که در کلاس Remoting Configuration قرار دارد را فراخواني کنيم و نام فايل پيکربندي را به عنوان آرگومان به آن بدهيم. برنامه ميزبان را به هر صورتي که بخواهيد ميتوانيد پيادهسازي کنيد.
ارسالي از طرف کاربر محترم : sm1372 /خ