نکته ای بر SignalR
پنجشنبه 20 آبان 1395در این مقاله قصد داریم شما را با دو مورد از مشکلاتی که در SignalR موجود است آشنا کنیم و برای حل این مشکل راه حلی را برگزینیم.
SignalR پیاده سازی ماکروسافت از WebSocket است که کانال های ارتباطی دو طرفه بیش از یک اتصال TCP را فراهم میکند.
اما این نکته فقط درباره ی ارسال سیگنال از سرور به browser صحبت میکند.
این نکته بر روی ساخت یک client proxy شخصی سازی شده ،برای رسیدگی به محدودیت های proxy تولید شده به صورت اتوماتیک توسط ماکروسافت که درزیر آمده است ، تمرکز کرده است :
• اگر اتصال شما دچار وقفه شود ، proxy تولید شده به صورت اتوماتیک، تلاشی برای ساخت اتصال جدید نمیکند.
• proxy تولید شده به صورت اتوماتیک بعد از ساخته شدن اتصال listeners های اضافه شده توسط کاربر را پشتیبانی نمیکند.
یک برنامه ASP.NET MVC application در Visual Studio 2015 (update 3) ساخته ایم.
اگرچه در اینجا موضوع broadcast، یک سیگنال به همه ی اتصالات مرورگر است که باید یک نقطه ی اغاز آسانی باشد.
محیط ServerSide :
برای استفاده از Signalr در پروژه ASP.NET MVC ، شما نیاز به اضافه کردن وابستگی های dependency در NuGet packages دارید.
شما نیاز به ساخت کلاس "Hub" دارید ، بنابراین مرورگرهای وب میتوانند از طریق WebSocket به سرور متصل شوند.
using Microsoft.AspNet.SignalR; namespace siganlR_example { public class SignalRHub: Hub { } }
• شما اسم کلاس "Hub" را میتوانید هر چیزی که میخواهید قرار دهید که ما در این جا آن را "SignalRHub" نامیده ایم.
این کلاس نیاز به زیر کلاس "Microsoft.AspNet.SignalR.Hub" دارید که از طریق NuGet package اضافه میشود.
• برای هدف این نکته ، ما فقط broadcast سیگنال ها برای همه ی اتصال ها مرورگر استفاده میکنیم. بنابراین ما این کلاس را خالی میگذاریم.
برای آنکه برنامه MVC از کلاس "SignalR" آگاه باشد شما نیاز به صدا زدن extension method به نام "()MapSignalR" روی اینترفیس "IAppBuilder" در شروع پروژه دارید.
public class Startup { public void Configuration(IAppBuilder app) { // Map the SignalR app.MapSignalR(); AreaRegistration.RegisterAllAreas(); RouteConfig.RegisterRoutes(RouteTable.Routes); } }
تابع "()MapSignalR" همه ی زیر کلاس های کلاس "Microsoft.AspNet.SignalR.Hub"در زمان startup برنامه جستجو میکند.
بنابراین web application میداند که کلاس های "Hub" هنگامی که مرورگر تلاش میکند به آنها متصل شود ، استفاده میشود.
محیط Client Side :
براساس استفاده از SignalR شما نیاز به کتابخانه جاوا اسکریپت SignalR سمت کاربر دارید.
<script src="@Url.Content("~/Scripts/jquery.min-3.1.0.js")"></script>
<script src="@Url.Content("~/Scripts/jquery.signalR-2.2.1.min.js")"></script>
• SignalR به jQuery وابستگی دارد، پس به کتابخانه jQuery هم نیاز دارید.
• شما میتوانید کتابخانه جاوا اسکریپت را از Nuget نصب کنید.
بدلیل مشکلات proxy تولید شده توسط ماکروسافت ما client proxy خودمان را در پوشه "SignalRClient.js" میسازیم :
var SignalRClient = function (url, hubName) { var self = this; var RECONNECT_IF_DISCONNECTED = true; var connectionUrl = url; var connection = $.hubConnection(); var proxy = connection.createHubProxy(hubName); // Register a dummy handler proxy.on('*', function () { }); var connectToServer = function () { connection.url = connectionUrl; connection.start() .done(function () { console.log('SignalR Connected ID=' + connection.id); }) .fail(function () { console.log('SignalR Connection failed'); }); }; connection.disconnected(function () { console.log('SignalR Disconnected'); // If 'RECONNECT_IF_DISCONNECTED' set the timer // to connect to the server until re-connected if (RECONNECT_IF_DISCONNECTED) { setTimeout(connectToServer, 5 * 1000); } }); self.on = function (caller, handler) { proxy.on(caller, handler); return self; }; self.connect = function () { RECONNECT_IF_DISCONNECTED = true; connectToServer(); }; self.disconnect = function () { RECONNECT_IF_DISCONNECTED = false; connection.stop(); }; };
• "SignalRClient
" یک نوع تابع سازنده JavaScript است.
• در شروع، این یک listener ساختگی را ثبت میکند ، که اجازه اضافه کردن listener ها را بعد از ساختن اتصال را میدهد.
• در رویداد "disconnected" ما یک کد را اضافه کرده ایم که اگر اتصال با وقفه مواجه شود سعی در اتصال دوباره یه سرور را بکند.
مثال :
این مثال ساده برای broadcast یک پیام برای مرورگر متصل شده به سرور :
protected void Application_Start() { Timer timer = new Timer(1000); timer.AutoReset = true; timer.Elapsed += (sender, e) => { StringBuilder sb = new StringBuilder(); sb.Append("Server Time: ") .Append("<span style=\"color: red\">") .Append(System.DateTime.Now.ToLongTimeString()) .Append("</span>"); IHubContext context = GlobalHost.ConnectionManager.GetHubContext<SignalRHub>(); context.Clients.All.JustSendAMessage(sb.ToString()); }; timer.Start(); }
• در این مثال ما یک تایمر در "Application_Start" برای ارسال زمان سرور به مرورگر قرار داده ایم.
• این مهم است که بدانید که ، "JustSendAMessage()" یک فراخوانی روی نوع های داینامیک است. که فقط متن "JustSendAMessage" مهم است. ما این متن را برای رساندن متن پیام به مرورگر هنگامی که ما یک listener ثبت میکنیم نیاز داریم.
برای رساندن متن از سرور ما یک "Index.cshtml" میسازیم :
<html> <body> <div id="spanMsg"></div> </body> </html>
و لینک ها را برای فایل های جاوا اسکریپت سمت کاربر به سند HTML اضافه میکنیم .
<script src="@Url.Content ("~/Scripts/jquery.min-3.1.0.js")"></script> <script src="@Url.Content ("~/Scripts/jquery.signalR-2.2.1.min.js")"></script> <script src="@Url.Content ("~/Scripts/SignalRClient.js")"></script>
$(document).ready(function () { var sClient = new SignalRClient ('@Url.Content("~/signalR")', 'signalRHub'); sClient.on('JustSendAMessage', function (msg) { $('#spanMsg').html(msg); }); sClient.connect(); });
• برای ساختن یک instance از "SignalRClient" ، شما نیاز به تهیه ی "url" و نام کلاس "hub" دارید:
- "url" همیشه در root پوشه های وب سایت است + "signalR/";
- نام "hub" به نام کلاس "SignalRHub" مربوط میشود.
• متد "ON" یک listener به پیام ارسال شده به وسیله "JustSendAMessage" نوع داینامیک، ثبت میکند.
اجرای برنامه :
اگر همه چیز را درست انجام داده باشد باید تصویر بالا را داشته باشید.
- C#.net
- 2k بازدید
- 2 تشکر