angularjs+signalr的即時同步
網路上針對signalr和jquery的範例非常多,angularjs的搭配範例比較少,我現在想做一個模擬一個api讓外部調用的,然後我們電腦就能即時的顯示資料在畫面上,範例雖然簡單,但這種例子其實非常多,比如詢價系統,甚至是不同系統的介接,這邊為了不要複雜化,我想用最簡單的方式,來紀錄一下也幫助本人無可救藥的回憶,未來可以自我回顧,首先我們一樣的就是先模擬做一個資料庫吧,細節我就不多說了,我之前的文章也有寫到如何用code first,以下會是我預設要建立的資料庫欄位
using System;
using System.ComponentModel.DataAnnotations.Schema;
namespace signalrDemo.Models
{
public class MarketPricer
{
public int Id { get; set; }
public string Bank { get; set; }
public string UserName { get; set; }
public int Price { get; set; }
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public DateTime CreateDate { get; set; }
}
}
接著我在Models裡面建立了DefaultConctext.cs,程式碼如下
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Web;
namespace signalrDemo.Models
{
public class DefaultContext:DbContext
{
public DefaultContext()
:base("DefaultConnection")
{
}
public DbSet<MarketPricer> MarketPricer { get; set; }
}
}
然後接著打開Package Manager Console,然後輸入enable-migrations如下圖
然後輸入add-migration init
這時候會產生一支時間日期_init.cs,打開然後把CreateDate = c.DateTime(nullable: false),改成CreateDate = c.DateTime(nullable: false,defaultValueSql:"GetDate()"),,這一行是要把CreateDate改成預設值是抓現在時間,如下圖
最後則是打下update-database
Signalr部份
接著我們必須要在nuget下載signalr,如下圖
再來我們在專案新增一支Startup.cs,程式碼如下
using Microsoft.Owin;
using Owin;
[assembly: OwinStartup(typeof(signalrDemo.Startup))] //signalrDemo是您的專案名稱
namespace signalrDemo
{
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.MapSignalR();
}
}
}
接著我再新增一個目錄夾,專門放一些hub的cs檔,命名為signalrHub,然後我再此目錄新增一支檔案叫做GetHub.cs
using System.Linq;
using Microsoft.AspNet.SignalR;
using signalrDemo.Models;
namespace signalrDemo
{
public class GetHub : Hub
{
DefaultContext db = new DefaultContext();
public void GetMarketData()
{
Clients.All.MarketData(db.MarketPricer.ToList()); //此行則是廣播client端去接收
}
}
}
我把預設的ValuesController.cs改成只有一個Post,因為我想要從web api直接去新增資料,這樣可以給異端去呼叫,如下
using Microsoft.AspNet.SignalR;
using signalrDemo.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web.Http;
using System.Web.Http.Cors;
namespace signalrDemo.Controllers
{
public class ValuesController : ApiController
{
DefaultContext db = new DefaultContext();
IHubContext hub = GlobalHost.ConnectionManager.GetHubContext<GetHub>(); //GetHub是我剛剛新增的GetHub.cs檔
// POST api/values
public void Post(MarketPricer emp)
{
db.MarketPricer.Add(emp);
db.SaveChanges();
hub.Clients.All.MarketData(db.MarketPricer.ToList()); //這行則是又主動呼叫client去接收新資料
}
}
}
angularjs部份
首先我們必須要在用到的頁面加入一支signalr的js檔,jquery則是必要加入的,我是直接加在_Layout.cshtml裡面,如下
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<title>@ViewBag.Title</title>
@Styles.Render("~/Content/css")
@Scripts.Render("~/bundles/modernizr")
</head>
<body ng-app="app">
<div class="container body-content">
@Scripts.Render("~/bundles/jquery")
<script src="~/Scripts/angular.js"></script>
<script src="~/Scripts/jquery.signalR-2.2.0.js"></script>
@Scripts.Render("~/bundles/bootstrap")
@RenderBody()
<hr />
<footer>
<p>© @DateTime.Now.Year - My ASP.NET Application</p>
</footer>
</div>
@RenderSection("scripts", required: false)
</body>
</html>
接著就是Index.cshtml部份,簡單做一個ng-repeat把資料陳列出來就好,說明我都寫在註解裡面了
<div ng-controller="FirstCtrl">
<table class="table">
<tr>
<th>Bank</th>
<th>UserName</th>
<th>Price</th>
<th>CreateDate</th>
</tr>
<tr ng-repeat="item in items">
<td>{{item.Bank}}</td>
<td>{{item.UserName}}</td>
<td>{{item.Price}}</td>
<td>{{item.CreateDate}}</td>
</tr>
</table>
</div>
<script>
angular.module('app', [])
.controller('FirstCtrl', function ($scope) {
var hub = $.hubConnection();
var proxy = hub.createHubProxy('GetHub'); //GetHub是伺服器端那支cs檔
proxy.on('MarketData', function (data) { //MarketData就是這行 Clients.All.MarketData(db.MarketPricer.ToList());
$scope.items = data;
$scope.$apply();
});
hub.start().done(function () {
proxy.invoke('GetMarketData'); //這則是一開始我就要先調用資料,所以去呼叫了GetHub.cs裡面的GetMarketData method
});
});
</script>
然後開啟畫面因為資料庫是空的,預設沒有資料,接著我就假設使用PostMan來發個post,新增一筆資料,我們就可以看到瀏覽器自動收到資料了,如下圖
上面的內容,再請大家多多指教。