ایجاد یک Notification ساده آب و هوا با استفاده از SignalR

یکشنبه 7 شهریور 1395

هدف ما در این مقاله ،ایجاد یک برنامه ساده اطلاع رسانی وضعیت آب و هوا است که در صورت تغییرات آب و هوایی، این را به تمام کاربران بصورت real Time اطلاع می دهد . که ما در این مقاله با ارائه یک مثال و توضیح آن ، بصورت مرحله به مرحله این مبحث را برای شما ارائه خواهیم داد .

ایجاد یک Notification ساده آب و هوا با استفاده از SignalR

معرفی :
 SignalR یک کتابخانه برای توسعه دهندگان Net. برای اضافه کردن توابع بلادرنگ به برنامه با استفاده از تکنولوژیهای  (ASP.NET Application, C# console Application, WPF Application, Windows phone Application etc) است . این کتابخانه Open Source بوده و شما میتوانید براحتی آن را از GitHub دانلود کنید . 

آدرس Git Hub برای SignalR این است :   https://github.com/signalr

هدف ما در اینجا ، ایجاد یک برنامه ساده اطلاع رسانی وضعیت آب و هوا است که در صورت تغییرات آب و هوایی ، این را به تمام کاربران بصورت real Time اطلاع می دهد . 

 پیشنیاز :
شما باید اطلاعات ابتدایی در مورد موارد زیر داشته باشید :

• C# 
• Asp.net
• JavaScript
• jQuery
• 
Socket Communication ( اجباری نیست )

استفاده از Code :

• ایجاد یک پروژه جدید :

با استفاده از net framewrok version 4.5. یک پروژه جدید با نام WeatherAppDemo ، ایجاد کنید .  ما از .net 4.5  استفاده میکنیم ، برای اینکه توانایی استفاده از آخرین نسخه SignalR 2.x را داشته باشیم . 

توجه داشته باشید که نام را تغییر ندهید ، چون در قسمت های بعدی نیز با این NameSpace کار داریم .



ما در اینجا یک پروژه Asp.net Mvc ایجاد کردیم ، اما شما میتوانید از تکنولوژی های دیگر مانند webForms و ... نیز استفاده کنید .

• اضافه کردن کتابخانه SignalR

1. nuget package manager را باز کنید .


 
2. sinalR را در NuGet جستجو کنید و روی اولین چیزی که پیدا کرد کلیک کنید . 



این تمامی کتابخانه های مورد نیاز برای ایجاد یک برنامه SignalR را به پروژه اضافه می کند . این دو کتابخانه 
Server library و Client library را اضافه خواهد کرد .

باید توجه داشته باشید که در جستجوی SignalR نتایج زیادی نمایش داده میشود ، خب ، سوالی که مطرح میشود این است که ، اگر روی گزینه دیگری کلیک کنید ، چه اتفاقی خواهد افتاد ؟ .
در حقیقت آنها کتابخانه های جداگانه ای از SignalR هستند که برای اهداف گوناگون استفاده میشوند ، اما ما به package کامل آن احتیاج داریم برای اینکه هدف ما ایجاد SignalR Server به خوبی Client  است .

3. اضافه کردن فولدر جدید با نام SignalR



هدف از این کار ، قرار دادن کدهای مربوط به SignalR در یک فایل جداگانه است . 


• پیکربندی SignalR

1. ساخت کلاس Hub 
یک کلاس جدید با نام ChatHub را در فولدر SignalR ایجاد کنید و کدهای زیر را در آن قرار دهید . 
 

using Microsoft.AspNet.SignalR;
using Microsoft.AspNet.SignalR.Hubs;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace WeatherAppDemo.SignalR
{
    public class ChatHub:Hub
    {
        [HubMethodName("change_weather")]
        public void ChangeWeather(int temperature)
        {
             //Clients is ConnectionContext, it holds the information about all the connection.
            //Others in 'Clients.Others' is holding the list of all connected user except the 
            // caller user (the user which has called this method) 
            //NotifyUser is a function on the clientside, you will understand it later.

            Clients.Others.NotifyUser(temperature);

        }

    }
}

چه کاری در اینجا انجام میشود :
a. کلاس chathub از یک کلاس hub ارث بری میکند ، و این بدان معناست که ما کلاس ChatHub را میسازیم برای اینکه شبیه hub of the communication عمل کند .
b. ما تعریف تابع ChangeWeather را داریم ، که یک پارامتر دما را می گیرد ، از سمت کاربر NotifyUser را فراخوانی میکند . 


2. 
Mapping hubs to the signalr pipeline

یک کلاس جدید با نام StartUp به فولدر SignalR اضافه کنید و کدهای زیر را در StartUp.cs قرار دهید :

 

using Microsoft.Owin;
using Owin;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
[assembly: OwinStartup(typeof(WeatherAppDemo.SignalR.StartUp))]

namespace WeatherAppDemo.SignalR
{
    public class StartUp
    {
        public void Configuration(IAppBuilder app)
        {
            app.MapSignalR();
        }
    }
}

ما در اینجا چه کاری را انجام می دهیم :
a.  ما با استفاده از پارامتر owinstartup  ، WeatherAppDemo.SignalR.StartUp را فراخوانی میکنیم که کلاس StartUp ما را initialize  خواهد کرد . 

b. در کلاس StartUp ، ما در حال استفاده از ()app.MapSignalR هستیم . که این SignalR hubs را در app builder pipeline طرح‌ریزی میکند . اگر ساده بیان کنیم ، این بدین معناست که hubs رو به signalr pipeline اضافه خواهد کرد ، این بدان معناست که شما با استفاده از url می توانید دسترسی داشته باشید . url (آدرس) signalR به فرم <websiteurlwithport>/signalr است . 

برای مثال : codeproject.com/signalr

خب ، اساسا ما دو کار انجام میدهیم ، ابتدا کلاس StartUp  را راه‌اندازی می کنیم و سپس Hubs را به signalr pipeline اضافه می کنیم . 

حال،کد را Compile کنیدو "/signalr/hubs" را به url ضمیمه کنید.شما تعدادی کدJavaScript خواهید داشت.  اگر توانستیدکه کدهای Javascript را ببینید،آنگاه شما موفق به پیکربندی یک signalR server
 شده اید . 




ساخت Client 

خب ، ما نیاز به ساخت دو Client داریم :

• ابتدا کسی که دما را تغییر میدهد . 
• دوم ، کسی که notification را دریافت می کند .

مراحل ایجاد یک  Basic javascript client :

• یک صفحه html ایجاد کنید .
• کتابخانه jquery.js را به صفحه اضافه کنید . 
• کتابخانه signalr.js را به صفحه اضافه کنید . 
• script ی مانند src="/signalr/hubs" را اضافه کنید . 
• برای ارتباط با signalr server چندین js code را باید بنویسید ( در ادامه کدها را خواهید دید . )

ایجاد 
ChangeWeather client :

مراحل زیر را برای ایجاد یک basic javascript client دنبال کنید و در مرحله آخر کدهای زیر را در بین تگ script قرار دهید .

 

var SignalrConnection;

function Connect() {
    //This will hold the connection to the signalr hub
    SignalrConnection = $.connection.chatHub;

    //connecting the client to the signalr hub
    $.connection.hub.start().done(function () {
        alert("Connected to Signalr Server");
    })
    .fail(function () {
        alert("failed in connecting to the signalr server");
    })

}

function ChangeWeather() {
    //get the temperature from a textfield with id txtTemprature
    var Temperature = document.getElementById('txtTemperature').value;

    //calling the ChangeWeather function on the signalr server
    SignalrConnection.server.change_weather(Temperature)
}


 در کد بالا ؛ بیشتر قسمت ها را با کامنت گذاری توضیح داده ایم .

حال ، شما احتمالا با دیدن قسمتی از کدهای jQuery تعجب کرده اید شبیه "$.connection" .
- خب چگونه ما از این استفاده میکنیم ؟ - در حقیقت script ی که شامل استفاده از src="/signalr/hubs" بود ، jqury را گسترش می دهد ، و عمل فوق را برای ما امکان پذیر می سازد . 

حال ، وقت طراحی و ظاهر صفحه html ما است . 

   

<body onload="Connect();">
<div style="text-align:center;">
    <input type="text" id="txtTemperature" />
    <button id="btnChange" onclick="ChangeWeather();">Change Weather</button>
</div>
</body>


فرض ما بر این است که شما با کدهای html آشنایی دارید ، به همین دلیل کدهای فوق را توضیح نمی دهیم . 
درنهایت ، ما client ی که دما را تغییر می دهد را ایجاد کردیم . 


ایجاد 
RecieveWeatherNotification client :

مراحل زیر را برای ایجاد یک basic javascript client دمبال کنید و در مرحله آخر کدهای زیر را در بین تگ script قرار دهید . 

 

var SignalrConnection
function Connect() {
    //This will hold the connection to the signalr hub
    SignalrConnection = $.connection.chatHub;

    //This will be called by signalr
    SignalrConnection.client.NotifyUser = function (temperature) {
        $('span').text(temperature);
    }

    //connecting the client to the signalr hub
    $.connection.hub.start().done(function () {
        alert("Connected to Signalr Server");
    })
    .fail(function () {
        alert("failed in connecting to the signalr server");
    })

}


توجه داشته باشید که "NotifyUser" در کد - "SignalrConnection.client.NotifyUser" یک تابع است که توسط signalR server فراخوانی میشود . 

design صفحه html کار ساده ای است ، کدهای زیر را چک کنید :

 

<div style="text-align:center;">
    Temperature : <span></span> ℃
</div>

حال ، هر چیزی که نیاز بود را ما داریم . حال ، زمان آن است که چیزایی را که ایجاد کرده ایم را چک کنیم . 

مراحل زیر را دنبال کنید :
• Compile the code 
• در یک tab جدید مرورگر RecieveWeatherNotification  را باز کنید .
•  هوا را در ChangeWeather.html عوض کنید و سپس در RecieveWeatherNotification.html ، دما را مشاهده کنید . 

توجه داشته باشید ، زمانی که RecieveWeatherNotification.html را برای اولین بار باز خواهید کرد . هیچ دمایی در آن وجود ندارد ، که اصلا خووب نیست - منظور ما این است که بهتر است که یک مقدار ابتدایی برای دما در نظر بگیرید . 


خب ، چه کاری باید انجام دهیم :

a. بهتر است که temperature را در یک متغیر static نگه داریم ، همین امر برای تمامی متغیر های ChatHub صدق میکند . 

b. زمانی که RecieveWeatherNotification.html  به SignalR server وصل خواهد شد ، آن 
SignalR server را برای گرفتن دما فراخوانی خواهد کرد . 

c. ما مجبور خواهیم بود که در ChatHub متدی(HubMethod) را ایجاد کنیم که برای گرفتن دمای جاری توسط RecieveWeatherNotification.html فراخوانی خواهد شد . تابع ، NotifyUser  سمت کاربر را برای تنظیم کردن مقدار دما ، فراخوانی خواهد کرد . 

اضافه کردن ویزگی های بیشتر :

بروز رسانی ChatHub :
در بالا توضیح دادیم که قصد انجام چه کاری را داریم ، پس تنها کاری که لازمه انجام دهید کپی کردن کد زیر در کلاس ChatHub و بروزرسانی آن است . 

 

using Microsoft.AspNet.SignalR;
using Microsoft.AspNet.SignalR.Hubs;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace WeatherAppDemo.SignalR
{
    public class ChatHub:Hub
    {
        //keeping temperature variable static will make the value temperature to be stored in         
        //memory permanently and will be equal to all the object of chathub.
        static int Temperature;
        
        [HubMethodName("change_weather")]
        public void ChangeWeather(int temperature)
        {
            //change the temperature
            Temperature = temperature;

            //Clients is ConnectionContext, it holds the information about all the connection.
            //Others in 'Clients.Others' is holding the list of all connected user except the             
            //caller user (the user which has called this method) 
            //NotifyUser is a function on the clientside, you will understand it later.
            Clients.Others.NotifyUser(temperature);
            
        }

        [HubMethodName("get_weather")]
        public void GetWeather()
        {
            //pushing the data only to the user which has called this method.
            Clients.Caller.NotifyUser(Temperature);
        }

    }
}


خب ، ما کلاس ChatHub را بروز رسانی کردیم ، حال اجازه دهید  متد GetWeather  را در سمت Client فراخوانی کنیم . 

بروز رسانی 
RecieveWeatherNotification.html :

برای بروزرسانی RecieveWeatherNotification.html کدهای زیر را جایگزین کد قبلی کنید :

 

var SignalrConnection
function Connect() {
    //This will hold the connection to the signalr hub
    SignalrConnection = $.connection.chatHub;

    //This will be called by signalr
    SignalrConnection.client.NotifyUser = function (temperature) {
        $('span').text(temperature);
    }

    //connecting the client to the signalr hub
    $.connection.hub.start().done(function () {
        GetWeather();
        alert("Connected to Signalr Server");
    })
    .fail(function () {
        alert("failed in connecting to the signalr server");
    })

}

function GetWeather() {
    //calling the GetWeather function on the signalr server
    SignalrConnection.server.get_weather()
}


چه کاری در اینجا انجام شد ؟! -

• ما یک متد با نام GetWeather  ساختیم که chathubmethod "get_weather" را فراخوانی خواهد کرد . 
• ما GetWeather را فراخوانی میکنیم ، زمانی که کاربر به signalR وصل است . 

خب ، کد را Compile کنید و همه چیز را چک کنید . 

این یک برنامه سادست ، اما حال شما توانایی ایجاد پروژه های پیچیده ای همچون :

• برنامه Chat
• notification بلادرنگ ، شبیه Facebook 
• بروز رسانی با فرکانس بالا برای بازی های آنلاین 
• و ... 



در خروجی خواهیم داشت که :




 

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

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

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

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

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