模块功能说明:
实现技术:sqlserver,MVC,WebAPI,ADO.NET,SignalR(服务器主动推送)
特殊车辆管理--->移动客户端采集数据存入数据库---->只要数据库数据有变化,服务端自动推送到Wbe页面展示(区别于传统的web请求)-->审核人员审核数据-->返回审核结果给移动客户端
在开发之前搜索了大量文档,也在QQ群咨询过群里的大牛,不少人都感觉比较懵逼的样子。有人建议使用ajax中的长连接,轮询等技术,最终还是决定使用SignalR技术实现页面刷新的效果:
搜索了不少博客园大牛有关于使用SignakR的博客,最后终于找到一个,也是我目前在项目中实现功能的Demo。
以下内容转自博客园园友,感谢大牛提供资料,在此借鉴,如有不妥,请联系删除。
原博客中的代码在项目使用中有问题,已在下面代码中解决。
环境
.net 4.6
vs2015
mvc5
sqlserver2008
1.
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]数据库要使用service broker
ALTER DATABASE DBName SET NEW_BROKER WITH ROLLBACK IMMEDIATE;
ALTER DATABASE DBName SET ENABLE_BROKER;初始化数据库
INSERT INTO CARINFO (CARNO,LNG,LAT,LOCDT) VALUES ('豫A12345','113.123','43.123',GETDATE())
2.新建MVC项目
安装SignalR包
Install-Package Microsoft.AspNet.SignalR
修改startup.cs
public partial class Startup
{ public void Configuration(IAppBuilder app) { ConfigureAuth(app); app.MapSignalR(); } }修改web.config,增加数据库连接字符串
<add name="ConnString" connectionString="data source=.;initial catalog=MySignalR;persist security info=True;user id=sa;password=yourpass;" providerName="System.Data.SqlClient" />
增加数据模
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; } }新建类
public class CarInfoHub : Microsoft.AspNet.SignalR.Hub
{ public static void Show() { IHubContext context = GlobalHost.ConnectionManager.GetHubContext<CarInfoHub>(); context.Clients.All.displayStatus(); } }业务实现
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 = {0}", 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(); } }修改Global.asax
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); }新建API
public class DefaultController : ApiController
{ readonly CarInfoRepository _repository = new CarInfoRepository(); // GET api/values public CarInfo Get(int id) { return _repository.GetData(id); } }修改控制器
public ActionResult Index()
{//这里只是测试功能,指定了车辆编号
ViewBag.ID = 1; return View(); }修改视图
@{
Layout = null;}<!DOCTYPE html><html><head> <meta name="viewport" content="width=device-width" /> <title>车辆实时跟踪</title> <script src="~/Scripts/-1.10.2.min.js"></script> <script src="~/Scripts/jquery.signalR-2.2.1.min.js"></script> <script src="~/signalr/hubs" type="text/"></script> <script type="text/javascript"> var maxID; (function () { var CarID = @ViewBag.ID; // Proxy created on the fly var job =(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.connection.hub.start(); getData(); }); function getData() { vartbl = ('#tblJobInfo');('#tblJobInfo');.ajax({ url: '../api/Default/'+CarID, type: 'GET', datatype: 'json', success: function (data) { tbl.empty();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>现在测试一下
update carinfo set
Lng = CAST(Lng as float)+0.0001,Lat = CAST(Lat as float)+0.0001,LocDt = getdate();