使用SignalR实时推送数据库变化
测试环境:.NET 4.6、VS2017、MVC5、SQLServer20081、新建数据库及表:
[quote]CREATE DATABASE SignalR;
CREATE TABLE [dbo].[CarInfo](
[ID] [int] IDENTITY(1,1) NOT NULL,
[CarNo] [varchar](50) NOT NULL,
[Lng] [varchar](50) NOT NULL,
[Lat] [varchar](50) NOT NULL,
[LocDt] [datetime] NOT NULL,
CONSTRAINT [PK_CarInfo] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO[/quote]
数据库要使用Service Broker(否则运行时会提示当前数据库未启用Service Broker):
[quote]ALTER DATABASE SignalR SET NEW_BROKER WITH ROLLBACK IMMEDIATE;
ALTER DATABASE SignalR SET ENABLE_BROKER;[/quote]
初始化数据库:
[quote]INSERT INTO CARINFO (CARNO,LNG,LAT,LOCDT) VALUES ('鲁S25171','113.111','222.112',GETDATE())[/quote]
2.新建MVC项目
2.1 安装SignalR包(解决方案资源管理器中右击解决方案-->管理NuGet程序包):
Install-Package Microsoft.AspNet.SignalR
2.2 修改Startup.cs:
[quote] public partial class Startup
{
public void Configuration(IAppBuilder app)
{
//ConfigureAuth(app);
[color=Red]app.MapSignalR();[/color]
}
}[/quote]
2.3 修改Web.config,增加数据库连接字符串( <connectionStrings></connectionStrings>中间):
[quote] <add name="ConnString" connectionString="data source=.;initial catalog=SignalR;persist security info=True;user id=sa;password=yourpass;" providerName="System.Data.SqlClient" />[/quote]
2.4 增加数据模(CarInfo.cs-->namespace SignalrDemo中):
[quote] public class CarInfo
{
public int ID { get; set; }
public string CarNo { get; set; }
public string Lng { get; set; }
public string Lat { get; set; }
public DateTime LocDt { get; set; }
}
[/quote]
2.5 新建类(CarInfoHub.cs-->namespace SignalrDemo中):
[quote] //public class CarInfoHub : Microsoft.AspNet.SignalR.Hub
public class CarInfoHub : Hub
{
public static void Show()
{
IHubContext context = GlobalHost.ConnectionManager.GetHubContext<CarInfoHub>();
context.Clients.All.displayStatus();
}
}[/quote]
2.6 业务实现(CarInfoRepository.cs-->namespace SignalrDemo中):
[quote] public class CarInfoRepository
{
public CarInfo GetData(int id)
{
using (var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnString"].ConnectionString))
{
connection.Open();
using (SqlCommand command = new SqlCommand($"SELECT [ID],[CarNo],[Lng],[Lat],[LocDt] FROM [dbo].[CarInfo] WHERE ID = {id}", connection))
{
command.Notification = null;
SqlDependency dependency = new SqlDependency(command);
dependency.OnChange += dependency_OnChange;
if (connection.State == ConnectionState.Closed)
connection.Open();
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
return new CarInfo()
{
ID = reader.GetInt32(0),
CarNo = reader.GetString(1),
Lng = reader.GetString(2),
Lat = reader.GetString(3),
LocDt = reader.GetDateTime(4)
};
}
}
}
}
return null;
}
private void dependency_OnChange(object sender, SqlNotificationEventArgs e)
{
CarInfoHub.Show();
}
}[/quote]
2.7 修改Global.asax:
[quote] protected void Application_Start()
{
GlobalConfiguration.Configure(WebApiConfig.Register);
SqlDependency.Start(ConfigurationManager.ConnectionStrings["ConnString"].ConnectionString);
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
protected void Application_End(object sender, EventArgs e)
{
SqlDependency.Stop(ConfigurationManager.ConnectionStrings["ConnString"].ConnectionString);
}[/quote]
2.8 新建API(Controllers-->DefaultController.cs-->namespace SignalrDemo.Controllers中):
[quote] public class DefaultController : ApiController
{
readonly CarInfoRepository _repository = new CarInfoRepository();
// GET api/values
public CarInfo Get(int id)
{
return _repository.GetData(id);
}
}[/quote]
2.9 修改控制器(Controllers-->HomeController.cs-->public class HomeController : Controller中):
[quote] public ActionResult Index()
{
//这里只是测试功能,指定了车辆编号
ViewBag.ID = 1;
return View();
}[/quote]
2.10 修改视图(Views-->Home-->Index.cshtml):
[quote]@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>车辆实时跟踪</title>
<script src="~/Scripts/jquery-1.10.2.min.js"></script> @*/需根据实际文件名修改*@
<script src="~/Scripts/jquery.signalR-2.2.1.min.js"></script> @*/需根据实际文件名修改*@
<script src="~/signalr/hubs" type="text/javascript"></script>
<script type="text/javascript">
var maxID;
$(function () {
var CarID = @ViewBag.ID;
// Proxy created on the fly
var job = $.connection.carInfoHub;
// Declare a function on the job hub so the server can invoke it
job.client.displayStatus = function () {
getData();
};
// Start the connection
$.connection.hub.start();
getData();
});
function getData() {
var $tbl = $('#tblJobInfo');
$.ajax({
url: '../api/Default/'+CarID,
type: 'GET',
datatype: 'json',
success: function (data) {
$tbl.empty();
$tbl.append(' <tr><th>ID</th><th>CarNo</th><th>Lng</th><th>Lat</th></tr>');
var str ='<tr><td>' + data.ID + '</td><td>' + data.CarNo + '</td><td>' + data.Lng + '</td><td>' + data.Lat + '</td></tr>';
$tbl.append(str);
}
});
}
</script>
</head>
<body>
<div>
<table id="tblJobInfo" style="text-align: center; margin-left: 10px">
</table>
</div>
</body>
</html>[/quote]
现在测试一下
update carinfo set
Lng = CAST(Lng as float)+0.001,
Lat = CAST(Lat as float)+0.001,
LocDt = getdate();
面页数据可以实时发生变化。
页:
[1]