مفاهیم پایه ASP.NET SignalR بخش دوم
Loading...
ASP.NET SignalR

بخش اول مفاهیم پایه ASP.NET SignalR و نحوه استفاده از PersistentConnection را به صورت یک دمو معرفی کرد. در این مقاله، نشان می دهیم که چگونه از Hub استفاده کنیم، چگونه سرویس های SignalR را مقیاس بندی نموده و چگونه با کدهای خود ظرفیت SignalR را توسعه دهیم. برای اطلاعات بیشتر لطفا اینجا SignalR کلیک کنید.

ASP.NET SignalR

برای استفاده از مثال های دانلود شده، لطفا پکیج های مربوط به SignalR را از NuGet واکشی نمایید، چرا که به دلیل حجم بالا برای آپلود آن ها را حذف کرده ایم.

Hub

Hub عمدتا در حال هدف قرار دادن RPC سرور-به-کلاینت و کلاینت-به-سرور می باشد. بر اساس PersistentConnection پیاده سازی می شود. اگر لازم باشد می توانیم چندین Hub را در یک اتصال ایجاد کنیم. هیچ تفاوتی در عملکرد ندارد که ما تمام متدهای خود را در یک Hub یا چندین Hub تعریف نماییم.

اجازه دهید یک empty web application ایجاد کرده و یک Hub ساده تعریف کنیم که یک پیام کلاینت را به همه کلاینت های متصل پخش (broadcast) می کند:

public class MyChatHub : Hub
{
    public async Task BroadcastMessage(string callerName, string message)
    {
        // Case-insensitive when the server RPC the client's methods
        await Clients.All.appendnewmessage(callerName, message);
    }
}

متد BroadcastMessage برای کد سمت کلاینت تعریف شده تا یک فراخوانی RPC به سرور انجام دهد. و BroadcastMessage یک فراخوانی RPC به متد appendNewMessage تمام کلاینت ها انجام می دهد. همانطور که کامنت درون کد نشان می دهد، زمانی که سرور فراخوانی RPC به کلاینت انجام می دهد، به حروف کوچک و بزرگ حساس نیست.

توجه داشته باشید که سمت کلاینت باید از نام های camel-cased، myChatHub و broadcastMessage برای ارجاع به MyChatHub و BroadcastMessage استفاده نمایند. این قانون احترام به قرارداد نام گذاری جاوا اسکریپت را نشان می دهد. اما همچنان می توانید سمت کلاینت را مجبور کنید که از نام های Pascal-cased استفاده کند. درواقع، می توانید سمت کلاینت را وادار کنید که هر نام حساس به حروفی که می خواهید استفاده نماید. اجازه دهید Hub ساده دیگری ایجاد کنیم که زمان فعلی سرور را برمی گرداند.

[HubName("PascalCasedMyDateTimeHub")]
public class MyDateTimeHub : Hub
{
[HubMethodName("PascalCasedGetServerDateTime")]
public async Task GetServerDateTime()
{
return await Task.Run(() => DateTime.Now);
}
 }

با استفاده از HubNameAttribute و HubMethodNameAttribute، می توان نام های هر سمت کلاینتی را برای Hub و متدهای آن مشخص نمود.
برای ثبت Hubهای خود، از تکه کد زیر در Global.asax.cs استفاده می کنیم:

public class Global : System.Web.HttpApplication
{
    protected void Application_Start(object sender, EventArgs e)
    {
        RouteTable.Routes.MapHubs("/myhubs", new HubConfiguration());
    }
}


در اینجا ما “/myhubs” را به عنوان ریشه URL برای همه Hubها با پیکربندی پیش فرض مشخص می کنیم. ما باید همه Hubهای خود را به یک ریشه URL در یک اپلیکیشن وب نگاشت کنیم. MapHubs یک متد توسعه داده شده است که در SignalR تعریف می شود. اگر آرگومان های MapHub را مشخص نکنیم، تمام Hubهای ما را “/signalr” نگاشت می کند. اما هنوز توصیه می شود که از URL خود استفاده کنید تا از نامعلومی و تداخل های اسمی بالقوه اجتناب شود.
دو راه در کدهای جاوا اسکریپت سمت کلاینت برای دسترسی به Hubهای سرور وجود دارد: استفاده از یک پروکسی که به صورت خودکار تولید می شود یا عدم استفاده از آن.
مثال اول ما استفاده از پروکسی تولید شده به صورت خودکار است. درواقع، ما لازم نیست هیچ کاری در سمت سرور انجام دهیم. فقط لازم است که یک خط در صفحه وب اضافه کنیم:

<head> 
    ...... 
    <script type="text/javascript" src="myhubs/hubs"></script>
</head>

“myhubs/hubs” به سرور می گوید که پروکسی تولید شده به صورت خودکار را ارسال کند – یک فایل جاوا اسکریپت در stream. URL باید با Hub URLای که نگاشت کرده ایم و کلمه “hubs” ترکیب شود. اگر از URL نگاشت شده پیش فرض – “signalr”-  استفاده کنیم، URL پروکسی ایجادشده باید به صورت “signalr/hubs” باشد.

قطعه کد زیر از index.html نشان می دهد که چگونه از Hubهای سرور استفاده کنیم:

$(function () {
    // Connect Hubs without the generated proxy
    var timeHubProxy = $.connection.PascalCasedMyDateTimeHub;
    var chatHubProxy = $.connection.myChatHub;
    // Register client function to be called by server
    chatHubProxy.client.appendNewMessage = function (clientName, message) {
        addMsg(clientName + ": " + message);
    };
    // Start the hub connection
    addMsg("...hubدر حال اتصال به ");
    $.connection.hub.start().done(function () {
        addMsg(" متصل شد.Hub");
        $("#refreshServerTime").click(function () {
            timeHubProxy.server.PascalCasedGetServerDateTime().done(function (serverTime) {
                $("#serverTime").text(serverTime);
            });
        });
        $("#send").click(function () {
            chatHubProxy.server.broadcastMessage($("#name").val(), $("#msg").val());
        });
    }).fail(function () {
        addMsg(" امکان پذیر نمی باشد.Hubاتصال به ");
    });
});

همانطور که مشاهده می کنید کد جاوا اسکریپت با استفاده از پروکسی تولید شده به صورت خودکار متدهای Hub سرور را درست مثل فراخوانی متدهای محلی فراخوانی می کند. توجه داشته باشید که ما متد appendNewMessage را در سمت کلاینت تعریف کردیم. این متد توسط سرور فراخوانی شده و حساس به حروف نیست.

مثال دوم ما Hubهای سرور را بدون پروکسی تولید شده به صورت خودکار استفاده می کند. این مثال با پیچیدگی بیشتری همراه است چرا که ما باید از متد Invoke به همین صورت که کد زیر از index_no_generated_proxy.html نشان می دهد، استفاده کنیم:

$(function () {
    // Connect Hubs without the generated proxy
    var connection = $.hubConnection("/myhubs");
    var timeHubProxy = connection.createHubProxy("PascalCasedMyDateTimeHub");
    var chatHubProxy = connection.createHubProxy("myChatHub");
    // Register client function to be called by server
    chatHubProxy.on("appendNewMessage", function (clientName, message) {
        addMsg(clientName + ": " + message);
    });
    // Start the hub connection
    addMsg("...hubدر حال اتصال به ");
    connection.start().done(function () {
        addMsg(" متصل شد.Hub");
        $("#refreshServerTime").click(function () {
            timeHubProxy.invoke("PascalCasedGetServerDateTime").done(function (serverTime) {
                $("#serverTime").text(serverTime);
            });
        });
        $("#send").click(function () {
            chatHubProxy.invoke("broadcastMessage", $("#name").val(), $("#msg").val());
        });
    }).fail(function () {
        addMsg(" امکان پذیر نمی باشد.Hubاتصال به ");
    });
});

اگر از نگاشت پیش فرض “/signalr” استفاده می کنیم، آرگومان – “/myhubs” نیازی نیست که اتصال را مقداردهی اولیه کند.

همچنین می توانیم یک کلاینت .NET برای فراخوانی Hubهای سرور بنویسیم. کد نوشته شده در Program.cs بسیار مشابه کد جاوا اسکریپت بدون پروکسی تولیدشده به صورت خودکار است:

static void Main(string[] args)
{
    // Almost the same usage as JavaScript without generated proxy
    var hubConn = new HubConnection("http://localhost:6473/myhubs");
    var timeHubProxy = hubConn.CreateHubProxy("PascalCasedMyDateTimeHub");
    var chatHubProxy = hubConn.CreateHubProxy("myChatHub");
    chatHubProxy.On("appendNewMessage", delegate(string name, string message)
    {
        Console.WriteLine("{0}: {1}", name, message);
    });
    hubConn.Start().Wait();
    string inputLine;
    while (!string.IsNullOrEmpty(inputLine = Console.ReadLine()))
    {
        Task t = timeHubProxy.Invoke("PascalCasedGetServerDateTime");
        t.Wait();
        Console.WriteLine((DateTime)t.Result);
        chatHubProxy.Invoke("broadcastMessage", "dzy", inputLine).Wait();
    }
}

URL کامل لازم است که اتصال Hub را مقداردهی اولیه کند. و به روشی که appendNewMessage تعریف می شود توجه داشته باشید.

مقیاس بندی

SignalR با کمک SQL Server، Redis یا Windows Azure Service Bus کار فوق العاده ای در مقیاس بندی خود در وب فرم انجام می دهد. همانطور که در بخش اول معرفی شد، پکیج های مختلفی برای این تکنولوژی های مختلف موجود است:

  • AspNet.SignalR.SqlServer: روتر پیام رسانی SQL Server
  • AspNet.SignalR.Redis: روتر پیام رسانی Redis
  • AspNet.SignalR.ServiceBus: روتر پیام رسانی Windows Azure Service Bus

به دلیل محدودیت محیط توسعه، در اینجا ما فقط مثالی  با SQL Server را ارائه می دهیم. نحوه استفاده در دو تکنولوژی دیگر نیز مشابه است.

اجازه دهید دموی Hub قبلی را به عنوان مثال در نظر بگیریم. برای فعال سازی مقیاس بندی با SQL Server، می توانیم مراحل زیر را دنبال کنیم:

یک دیتابیس جدید با هر نام دلخواهی که می خواهیم در SQL Server ایجاد می کنیم. فرض می کنیم نام آن SignalRScaleOut باشد. زمانی که دموی Hub برای اولین بار اجرا می شود SignalR جدول های موردنیاز را خواهد ساخت.

یک لاگین جدید در SQL Server می سازیم. نام لاگین و پسورد آن را “signalr” قرار می دهیم و دسترسی db_owner را برای دیتابیس SignalRScaleOut اعطا می کنیم. این مرحله اجباری نیست، اما ایجاد یک کاربر مشخص برای این دیتابیس بسیار امن تر است. فراموش نکنید که هنگام ایجاد یک لاگین جدید تیک “Enforce password policy” و “Enforce password expiration” را بردارید.

قوانین واردشونده (inbound) فایروال ویندوز را پیکربندی می کنیم تا اجازه اتصالات خارجی به SQL Server را بدهد.

پکیج Microsoft.AspNet.SignalR.SqlServer را از طریق NuGet در پروژه دموی Hub server نصب می کنیم.

در فایل Global.asax.cs متد Application_Start را به صورت زیر تغییر می دهیم:

public class Global : System.Web.HttpApplication
{
    protected void Application_Start(object sender, EventArgs e)
    {
        string connectionString = "server=127.0.0.1;uid=signalr;pwd=signalr;database=SignalRScaleOut";
        GlobalHost.DependencyResolver.UseSqlServer(connectionString);
        RouteTable.Routes.MapHubs("/myhubs", new HubConfiguration());
    }
} 

در اینجا ما SignalR را با connection string مشخصی به منظور فعال سازی مقیاس بندی برای استفاده SQL Server پیکربندی می کنیم. آدرس IP ‘۱۲۷.۰.۰.۱’ باید به آدرس دقیق ماشین SQL Server ما تغییر نماید.

حالا کار مقیاس بندی تمام شد. می توانیم دموی Hub server تغییریافته را به ۲ یا چند ماشین متفاوتی که IIS را نصب دارند، کپی کنیم. خواهیم دید که زمانی که اپلیکیشن ها را در مرورگرها اجرا کرده و به سرورهای مختلف متصل می شویم، همه Hub server های ما داده یکسانی را به اشتراک می گذارند.

اگر Service Broker را در SQL Server فعال کنیم کارایی بهتری خواهیم داشت. برای بررسی اینکه Service Broker برای دیتابیس فعال است یا خیر، می توان کوئری زیر را در Management Studio نوشت:

select [name],[service_broker_guid],[is_broker_enabled] 
from [master].[sys].[databases]  

در dataset ای که برگردانده می شود، مقدار ستون is_broker_enabled را بررسی می کنیم. “۱” به معنی فعال و “۰” به معنی غیرفعال می باشد. دستور SQL زیر Service Broker را برای دیتابیس SignalRScalOut فعال می کند:

ALTER DATABASE SignalRScaleOut SET ENABLE_BROKER 

توسعه پذیری

برای توسعه پذیری آسان، SignalR قانون تزریق وابستگی های زیر را طراحی کرده است. می توان پیاده سازی اغلب کامپوننت های SignalR را از طریق GlobalHost.DependencyResolver همان طور که قطعه کد قبلی نشان می دهد، جایگزین کرد. برای مثال، اگر ما بخواهیم از JSON Serializer خود استفاده کنیم، می توانیم اینترفیس IJsonSerializer را پیاده سازی کرده و آن را به شکل قطعه کد زیر ثبت نماییم:

public class Global : System.Web.HttpApplication
{
    protected void Application_Start(object sender, EventArgs e)
    {
        GlobalHost.DependencyResolver.Register(
            typeof(IJsonSerializer), 
            () => new MyJsonSerializer());
        RouteTable.Routes.MapHubs("/myhubs", new HubConfiguration());
    }
}

توجه داشته باشید که اگرچه ما می توانیم از پیاده سازی JSON serializer خود استفاده کنیم، هنوز هم می توانیم فقط از سریال سازی متن استفاده کنیم چرا که SignalR برای استفاده از TextReader و TextWriter به صورت داخلی hardcode شده است.

GlobalHost.DependencyResolver اینترفیس IDependencyResolver را پیاده سازی می کند. بنابراین حتی می توانیم به شکل زیر آن را با پیاده سازی خود جایگزین کنیم:

public class Global : System.Web.HttpApplication
{ 
    protected void Application_Start(object sender, EventArgs e)
    {
        GlobalHost.DependencyResolver = new MyDependencyResolver();
        RouteTable.Routes.MapHubs("/myhubs", new HubConfiguration());
    }
}  

خلاصه

مباحث مقدماتی SignalR در این قسمت به پایان رسید. برای موضوعات  پیشرفته،مقالات بعدی ما را دنبال کنید با شما خواهیم بود.



 دانلود فايلهاي پروژه
  • پسورد: www.mspsoft.com


avatar فاطمه زکایی

فاطمه زکایی هستم. فارغ التحصیل کارشناسی مهندسی نرم افزار، مدت سه سال هست که در زمینه توسعه اپلیکیشن های تحت وب و اندروید و همچنین تولید محتوای تخصصی برنامه نویسی تحت وب و اندروید در مجموعه mspsoft در خدمت شما هستم.

آخرین مطالب و تخفیفات در کانال تلگرام :) کانال تلگرام ام اس پی سافت
مطالب مرتبط
ديدگاه خود را ارسال کنيد


محبوب ترين ويدئو هاي انلاين
دوره برنامه نویسی فروشگاه اینترنتی
  • تعداد اعضا 80k
  • قيمت دوره۱۰۰,۰۰۰ تومان
  • امتيازدهي
    1 vote, average: 5٫00 out of 51 vote, average: 5٫00 out of 51 vote, average: 5٫00 out of 51 vote, average: 5٫00 out of 51 vote, average: 5٫00 out of 5( 5٫00 از 1 رای )
    Loading...
دوره آموزشی سیستم ثبت سفارش آنلاین
  • تعداد اعضا 80k
  • قيمت دوره۵۰,۰۰۰ تومان
  • امتيازدهي
    1 vote, average: 5٫00 out of 51 vote, average: 5٫00 out of 51 vote, average: 5٫00 out of 51 vote, average: 5٫00 out of 51 vote, average: 5٫00 out of 5( 5٫00 از 1 رای )
    Loading...
دوره طراحی سیستم مدیریت مشتریان
  • تعداد اعضا 80k
  • قيمت دوره۵۰,۰۰۰ تومان
  • امتيازدهي
    1 vote, average: 5٫00 out of 51 vote, average: 5٫00 out of 51 vote, average: 5٫00 out of 51 vote, average: 5٫00 out of 51 vote, average: 5٫00 out of 5( 5٫00 از 1 رای )
    Loading...