测试环境:.NET 4.6、VS2017、MVC5、SQLServer2008 
 
1、新建数据库及表: 
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  
 
数据库要使用Service Broker(否则运行时会提示当前数据库未启用Service Broker): 
ALTER DATABASE SignalR SET NEW_BROKER WITH ROLLBACK IMMEDIATE; 
ALTER DATABASE SignalR SET ENABLE_BROKER;  
 
初始化数据库: 
INSERT INTO CARINFO (CARNO,LNG,LAT,LOCDT) VALUES ('鲁S25171','113.111','222.112',GETDATE())  
 
2.新建MVC项目 
 
2.1 安装SignalR包(解决方案资源管理器中右击解决方案-->管理NuGet程序包): 
Install-Package Microsoft.AspNet.SignalR 
 
2.2 修改Startup.cs: 
    public partial class Startup 
    { 
        public void Configuration(IAppBuilder app) 
        { 
            //ConfigureAuth(app); 
            app.MapSignalR(); 
        } 
    }  
 
2.3 修改Web.config,增加数据库连接字符串( <connectionStrings></connectionStrings>中间): 
    <add name="ConnString" connectionString="data source=.;initial catalog=SignalR;persist security info=True;user id=sa;password=yourpass;" providerName="System.Data.SqlClient" />  
 
2.4 增加数据模(CarInfo.cs-->namespace SignalrDemo中): 
    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; } 
    }  
2.5 新建类(CarInfoHub.cs-->namespace SignalrDemo中): 
    //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(); 
        } 
    }  
 
2.6 业务实现(CarInfoRepository.cs-->namespace SignalrDemo中): 
    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(); 
        } 
    }  
 
2.7 修改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); 
        }  
 
2.8 新建API(Controllers-->DefaultController.cs-->namespace SignalrDemo.Controllers中): 
    public class DefaultController : ApiController 
    { 
        readonly CarInfoRepository _repository = new CarInfoRepository(); 
 
 
        // GET api/values 
        public CarInfo Get(int id) 
        { 
            return _repository.GetData(id); 
        } 
    }  
 
2.9 修改控制器(Controllers-->HomeController.cs-->public class HomeController : Controller中): 
        public ActionResult Index() 
        { 
 
//这里只是测试功能,指定了车辆编号 
            ViewBag.ID = 1; 
            return View(); 
        }  
 
2.10 修改视图(Views-->Home-->Index.cshtml): 
 
@{ 
    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>  
 
现在测试一下 
 
update carinfo set  
Lng = CAST(Lng as float)+0.001, 
Lat = CAST(Lat as float)+0.001, 
LocDt = getdate(); 
 
面页数据可以实时发生变化。 |