signalR در Asp.net Core (پیامد ها و راه حل ها)

سه شنبه 26 اردیبهشت 1396

در این مقاله به توضیح در مورد نحوه استفاده از SignalR در Asp.net Core مشکلات و راه حل ها به همراه یک مثال می پردازیم .

signalR در Asp.net Core (پیامد ها و راه حل ها)

SignalRیک framwork برای بروزرسانی های بلادرنگ در نرم افزار است .همچنین ویزگی هایی دارد که می توان برای به روز رسانی های زنده در نرم افزار استفاده شود .
به زبان ساده SignalR ارتباط بین کلاینت و سرور را مدیریت میکند . مدیریت ارتباط به این معنا که می تواند با مرورگرهای منسوخ شده نیز سازگار شود به این صورت که از تکنولوژی مورد استفاده دراین مرورگرها استفاده میکند.
Web sockets نیز در Asp.net core در دسترس است اما نیاز به افزودن عملکردهای بسیاردارد . از این رو چرا ازSignalR استفاده نکنیم که هرچیزی که ما نیازداریم را دارد؟
signalR در سرور یک کلاس Hub دارد که از طریق هاب Proxy با کلاینت ارتباط برقرار می کند.

زمانی که شما از پراکسی استفاده می کنید شما می توانید ارتباط بین کلاینت و سرور را با فراخوانی متد های آنها برقرار کنید .SignalR مدیریت ارتباط با کلاینت را بر عهده دارد.
ارتباط:
در معماری های سنتی  زمانی که سرور به یک درخواست پاسخ میداد کانکشن یا سایر اطلاعات برای حاضر نگه داشتن ارتباط را نگه نمی  داشت . اما در SignalR سرور اطلاعات کانکشن را نگه میدارد همچنین مامیتوانیم از سرور به کلاینت ارتباط بازگشتی داشته باشیم .
در تعریف ساده تر فرض کنید یک نرم افزار چت با 10 کاربر آنلاین موجود است . SignalR هویت کاربران را میداند و شما می توانید هر کدام از آنها را برای ارسال پیام و یا فراخوانی متد کلاینت  مورد هدف قرار دهید.
کلاس Hub:
این کلاس دروازه ی همه ی ارتباط هاست . برای ساخت این کلاس  لازم است کلاس شما از کلاس Hub ارث بری کند .

کلاس Hub می تواند شامل تمامی متد های سرور که می توان از کلاینت فراخوانی کرد یا هر کتاب خانه ی دیگری با استفاده از Hub Context باشد.
همچنین اگر IHubType را یک اینترفیس که شما می توانید در هر جایی ساخته یا استفاده کنید فرض کنید . شما می توانید بک strong type از Hub public class به صورت Hub<IHubType> داشته باشید .
Hub Proxy:
Hub Proxy کلاس اصلی است که برای ساخت کانکشن در سمت کلاینت استفاده می شود .در این کانکشن شما یک پراکسی می سازید و روی این پراکسی توابع خود را تعریف میکنید.توابع سمت کلاینتی که قابلیت فراخوانی مستقیم از طرف متد Hub Server یا کانتکس SignalR Hub قرار گرفته در کتابخانه مجزا را دارد.
انواع پراکسی :
دو نوع Hub پراکسی وجود دارد.می توانید یک پراکسی  اتوماتیک داشته باشید. برای اینکار کافیست دو اسکریپت زیر را به کد خود بیافزایید.

در صورتی که از پراکسی غیر اتوماتیک استفاده می کنید نیازی به ین کار نیست.
ایده اصلی:
در گذشته تکنیک های زیادی برای ارتباط بلادرنگ سرور و کلاینت موجود بودمانند Long pooling،Forever Connection و...، روش هایی برای ایجاد ارتباط و روشهایی برای بروز رسانی بلادرنگ استفاده می شد.
SignalR کار را بسیار راحت کرده . به این صورت که ارتباط بین سرور و کلاینت را برای استفاده از جایگزین های متفاوت فراهم مدیریت می کند. اگر یک متد توسط مرورگر پشتیبانی نشود .از متد دیگری استفاده می کنید برای مثال اگر Web sockets پشتیبانی نشود Long pooling یا Forever Connection یا هر روش مناسب دیگری را جایگزین میکند.در هر صورت در دسترس خواهد بود.
Web sockets در Asp.net Core در دسترس است اما برای مدیریت ان نیاز به کارهای بیشتری داریم . برای مثال فرا خوانی تمامی گروهی که می خواهیم با آنها ارتباط برقرار کنیم .در SignalR همه چیز فراهم شده است.

تمرین:
یک پروژه بسازید .

یک قالب برای پروژه خود انتخاب کنید.

 اماده شدن پروژه:

پکیج های سمت سرور:
در پروژه یک پوشه با نام Hubs بسازید.

در پوشه Hubs یک کلاس با نام InfoHub ایجاد کنید ، ما می توانیم از مشخصه HubName برای Hub استفاده کنیم تا در زمانی که از پراکسی  بتوانیم از سمت کلاینت نام آن را تشخیص دهیم اما برای ساده شدن کار ازآن صرف نظر می کنیم .
ما بسته SignalR را نصب نکرده ایم اما ویژوال استودیو به ما پیشنهاد میدهد . بر روی پیشنهاد مبنی بر افزودن بسته کلیک کنید تا بسته SignalR به پروژه اضافه شود. اینکار یک رفرنس در project.json اضافه می کند و فایل مربوطه را در پوشه Packages نصب خواهد کرد.

ایجاد تغییرات در کلاس Hub :
زمانی که تمامی کار های فوق به پایان رسید .می توانیم نام بسته های نصب شده را در فایل project.json ببینیم.

اکنون زمان راه اندازی SignalR و استفاده از آن در نرم افزار تحت وب می باشد. در فایل Startup.cs متد های زیر را فراخوانی کنید.


متد HandShake() را در کلاس InfoHub اضافه کنید.زمانی که کانکشن پراکسی از سمت کلاینت ساخته شد. ما یک پیغام خوشامد گویی برای تمام کاربران ارسال میکنیم .


برای سمت کلاینت:
در سمت کلاینت ما نیاز به بسته jQuery داریم که SignalR را پشتیبانی کند.تا با مشکلاتی مثل عدم شناسایی متغیر های اساسی مواجه نشویم.
فایل مورد نیاز فایل “jquery.signalR-2.2.0” است که در فایل ضمیمه مقاله قرار گرقته است. کافیست فایل مورد نظر را در پوشه جاوااسکریپت پروژه خود کپی کنید.


اسکریپت های مورد نظر را در فایل Layout اضافه کنید. دقت کنید ~/signalr/hubs به صورت فیزیکی در پروژه وجود ندارد.
در فایل index.cshtml ما نیاز به یک نمونه از کلاس  InfoHub داریم ، دقت کنید که در این قسمت کارکتر اول نام کلاس به صورت کوچک خواهد امد و ما نام کلاس را به صورت infoHub داریم .
در متد document Ready ما متد welcome را با یک پارامتر ورودی تعریف خواهیم کرد. این متد پس از دریافت ورودی از فراخواننده آن را در المان div با شناسه “dvInfo” قرار میدهد.
هر زمان کسی این صفحه را ببیند. نمونه ای از کلاس Hub مقدار دهی اولیه خواهد شد و زمانی که نمونه مورد نظر شروع به کار کند.متد handShake() را از Hub را فراخوانی خواهد کرد. این امر موجب میشود که سرور پیام را برای همه کاربر ها ارسال کند.

الان همه چیز حاضر است و شما می توانید از SignalR استفاده کنید.

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


ذخیره کردن اطلاعات کانکشن:
ما یک دیکشنری ازداده های مربوطبه کانکشن ها در دسترس داریم که می توانیم از آن برای نگهداری کانکشن تمام کاربران استفاده کنیم این دیکشنری متد هایی برای ارسال پیام برای تمامی کاربران همچنین انتخاب یک کاربر خاص و یا گروهی از کاربران را برای ما فراهم میکند. برای استفاده از آن کافیست از مشخصه ی Clients و متد های آن استفاده کنید.

چگونگی استفاده از Hub در یک کتابخانه مجزا:
در معماری لایه ای ما می توانیم از یک کتابخانه ی مجزا که حاوی کلاس Hub باشد استفاده کنیم .
برای این کار یک Class librery به پروژه ی خود اضافه کنید.

در کتابخانه خود یک پوشه به نام Hubs برای کلاس Hub جدیدی اضافه کنید. کلاس InfoHub را اضافه کنید و محتویات آن را از نمونه ای که در پروژه اصلی قرار دارد کپی کنید.
این کار درخواست نصب SignalRرا به دنبال دارد به ویژوال استودیو اجازه ی اینکار را بدهید.
زمانیکه همه این کارها انجام شد. چیزی شبیه عکس زیر داشته باشیم.

اکنون پوشه Hubs را از پروژه اصلی حذف کنید.و کتابخانه حاوی Hubs را به پروزه ارجاع دهید.

پروژه را اجرا کنید باید همانند قبل کارکند.
فراخوانی متد Hub از کتابخانه درکلاس هایی که از نوع Hub نیستند:
زمانی که می خواهید متدHub را از کلاسی که از نوع Hub  نیست فراخوانی کنید باید فضای نامی زیر را به کلاس مورد نظر اضافه کنید.

و کلاس مورد نظر باید یک نمونه از اینترفیس IConnectionManager را ایجاد کند به صورت زیر

زمانی که یک نمونه از اینترفیس  IConnectionManager در کلاسی که از نوع Hub نیست دارید می توانید از Context استفاده کنید و متد های سمت سرور و کلاینت را مستقیما فراخوانی کنید.
پیامد های استفاده از SignalR به همراه AngularJs و راه حل های آن:
مشکل موجود در استفاده ی SignalR به همراه Angular بستن کانکشن ها در زمان درست میباشد. زمانی که در یک SPA بین صفحات حرکت می کنیم در حقیقت تنها متحوای المانdiv تغییر می کند و صفحه مورد نظر رفرش نخواهد شد.این امر باعث میشود کانکشن های SignalR همچنان باز بمانند.
یکی از راح حل های رایج استفاده از windows.location.href است که در SPA چندان مناسب نیست زیرا هدف اصلی SPA رفرش نشدن صفحه است.راه حل اساسی ایجاد یک متغیر Global در فایل Js اصلی که معمولا نام app.js را دارد و استفاده از این متغیر ها برا کانکشن SignalR  در controller مربوطه است. سپس درapp.run  ما نیاز به یک متد $routeChangeStart داریم که درهربار تغییر صفحه اجرا خواهد شد. در این متد میتوانیم کانکشن را به موقع ببندیم.
ما یک متغیر Global در app.js ایجاد میکنیم به نام monitorHubConnection سپس در viewController مانند monitorController.js آن را مقدار دهی اولیه می کنیم .و سپس در app.js با هر تغییرمسیر آن را می بندیم.
ماننده عکس زیر

آموزش asp.net mvc

فایل های ضمیمه

برنامه نویسان

نویسنده 3355 مقاله در برنامه نویسان

کاربرانی که از نویسنده این مقاله تشکر کرده اند

در صورتی که در رابطه با این مقاله سوالی دارید، در تاپیک های انجمن مطرح کنید