نکته ای بر SignalR

پنجشنبه 20 آبان 1395

در این مقاله قصد داریم شما را با دو مورد از مشکلاتی که در SignalR موجود است آشنا کنیم و برای حل این مشکل راه حلی را برگزینیم.

نکته ای بر 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" نوع داینامیک، ثبت میکند.

اجرای برنامه :

اگر همه چیز را درست انجام داده باشد باید تصویر بالا را داشته باشید.

آموزش سی شارپ

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

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

نویسنده 3355 مقاله در برنامه نویسان
  • C#.net
  • 2k بازدید
  • 2 تشکر

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

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