sql server主动推送客户端更新数据
小谈需求:
最近工作上接到一个需求,做一个web展示数据的报表,最好能实时更新,不限制所用技术。
第一个问题:web服务器推送给浏览器新数据,一开始我想到的最快的最简单的方法就是 在web页面上js轮询了。因为我们的数据更新频率并不快。 后来觉得这种办法有点太土了。 或许长轮询更有效。 当然长轮询的技术很多了。 java 的dwr,c#的 signalr。c#还可以同过异步请求来自己写长轮询。
遇到的第二个问题,就是数据库如何通知web服务器更新数据,下面便是sql server2008的推送了,通过sql server的触发器,当数据表有变化时(增,删,改)就通过tcp请求服务器,服务器会在启动后开启端口一直监听,随时等待通信请求。当收到请求后,就从数据库读取新数据,推送给浏览器。整体大概就这样。
下面是数据库通知服务器。这是一个 winform的demo ,winfom就相当于我们展示数据的服务器了。
最后demo图:

现在我插入一条数据:

然后再看那个客户端:

刚插入的数据已经出现了哦。
客户端代码:
winform:
程序启动后,开启端口监听,如果有收到通信,则通知 dataview更新数据。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
|
using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Data.SqlClient;using System.Drawing;using System.Linq;using System.Net;using System.Net.Sockets;using System.Text;using System.Windows.Forms;using System.Threading;namespace sql_dependency{ public partial class Form1 : Form { public Form1() { InitializeComponent(); } System.Data.SqlClient.SqlConnection conn = null; string _connstr = "Data Source = 10.6.154.251; database=Temp;user id=sa;pwd=MOcyou0543_"; System.Data.SqlClient.SqlCommand command = null; private void Form1_Load(object sender, EventArgs e) { conn = new System.Data.SqlClient.SqlConnection(_connstr); command = conn.CreateCommand(); command.CommandText = "select [A],[B],[C] From [Temp].[dbo].[Simple]"; SqlDependency.Start(_connstr);//启动 Thread t = new Thread(new ThreadStart(GetData)); t.Start(); } private void GetData() { SetData(); IPAddress localAddr = IPAddress.Parse("127.0.0.1"); TcpListener tcplistener = new TcpListener(localAddr, 10010); tcplistener.Start(); byte[] btServerReceive = new byte[2048]; string strServerReceive = string.Empty; while (true) { TcpClient tcp = tcplistener.AcceptTcpClient(); Console.WriteLine("Connected!"); NetworkStream ns = tcp.GetStream(); int intReceiveLength = ns.Read(btServerReceive, 0, btServerReceive.Length); strServerReceive = Encoding.ASCII.GetString(btServerReceive, 0, intReceiveLength); SetData(); tcp.Close(); } } private delegate void ChangeDataView(); private void SetData() { if (this.InvokeRequired) { this.Invoke(new ChangeDataView(SetData)); } else { using (SqlDataAdapter adapter = new SqlDataAdapter(command)) //查询数据 { System.Data.DataSet ds = new DataSet(); adapter.Fill(ds, 0, 100, "Simple"); dataGridView1.DataSource = ds.Tables["Simple"]; } } } private void Form1_Closed(object sender, FormClosedEventArgs e) { //清理现场 SqlDependency.Stop(_connstr); conn.Close(); conn.Dispose(); } }} |
数据库与clr集成,编写写dll:SqlDependency.dll,sql server将在可编程性中加载此dll,
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
|
using System;using System.IO;using System.Net;using System.Net.Sockets;using Microsoft.SqlServer.Server;using System.Net.Sockets;namespace SqlDependency{ public class Program { [SqlFunction(IsDeterministic = true, DataAccess = DataAccessKind.Read)] public static String WriteStringToFile(String FileFullPath, String Contend) { FileInfo Fi = new FileInfo(FileFullPath); if (!Fi.Directory.Exists) { Fi.Directory.Create(); } using (StreamWriter rw = File.CreateText(FileFullPath)) { rw.WriteLine(Contend); TcpClient tcpClient = new TcpClient(); try { if (tcpClient == null) { tcpClient = new TcpClient(); tcpClient.ReceiveTimeout = 20000; } if (tcpClient.Connected == false) { System.Net.IPAddress address = System.Net.IPAddress.Parse(Contend); System.Net.IPHostEntry ipInfor = System.Net.Dns.GetHostByAddress(address); string hostName = ipInfor.HostName; IPEndPoint serverEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 10010); tcpClient.Connect(serverEndPoint); rw.Write(hostName); } rw.Write("连接成功,先发送指令"); // Translate the passed message into ASCII and store it as a Byte array. Byte[] data = System.Text.Encoding.ASCII.GetBytes("new data!"); NetworkStream stream = tcpClient.GetStream(); // Send the message to the connected TcpServer. stream.Write(data, 0, data.Length); stream.Close(); } catch (Exception e) { rw.Write(e.Message); } tcpClient.Close(); rw.Flush(); rw.Close(); return ""; } } }} |
接下来,便开始配置sql server啦:
首先开启sql server的clr支持:
|
1
2
3
4
5
|
开启数据库CLR 支持--exec sp_configure 'clr enabled', 1;--开始数据的验证alter database dbname set TRUSTWORTHY on;RECONFIGURE |
接着在sql server 2008中,新建查询窗口。加载刚才编写的dll SqlDependency.dll,并注册方法,然后写触发器,当表数据有变化时,触发函数。:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
use Temp;--数据库名create assembly SqlDependency FROM 'D:\SqlDependency.dll'--程序集名称和地址WITH PERMISSION_SET = UNSAFEGO--方法名写正确,为程序集中的方法名,注意参数个数create function WriteStringToFile(@FileFullName as nvarchar(max), @FileContend AS nvarchar(max))returns nvarchar(max)with returns null on null inputexternal name [SqlDependency].[SqlDependency.Program].[WriteStringToFile]GO--编写触发器,传递参数以及CREATE TRIGGER [dbo].[UserTableChangedEvent] on [dbo].[Simple] FOR INSERT, DELETE, UPDATE AS BEGIN DECLARE @Contend AS VARCHAR(100) DECLARE @FileName AS VARCHAR(MAX) SET @FileName ='D:\\MSG\\'+CONVERT(varchar(12) , getdate(), 112 )+'\\'+ convert(nvarchar(50), NEWID())+'.TXT' SET @Contend = '127.0.0.1'; Select dbo.WriteStringToFile(@FileName, @Contend) END GO |
注意,我的应用程序和 数据库在一台服务器上,所以地址都是127.0.0.1.可跟据实际填写正确地址。
再次在sql server中新建一个查询窗口,插入语句,进行测试吧。
如果过程中有问题,需要更新程序,方便地删除之上所创建的几个东东:
|
1
2
3
|
drop TRIGGER [dbo].[UserTableChangedEvent] drop function WriteStringToFiledrop assembly SqlDependency |
之后将尝试在web 结合 signal实现实时推送数据给web页面。等待下篇。
sql server主动推送客户端更新数据的更多相关文章
- DT7.0主动推送当天高质量图片数据到熊掌号展现
<?php /* 百度当天主动推送熊掌功能 作者:68喜科技 用于:DT7.0 功能模块:优质内容推送熊掌*出图内容当天推送 */ //引入全局变量函数 defined('IN_DESTOON' ...
- SQL Server ->> DISABLE索引后插入更新数据再REBUILD索引 和 保留索引直接插入更新数据的性能差异
之前对于“DISABLE索引后插入更新数据再REBUILD索引 和 保留索引直接插入更新数据的性能差异”这两种方法一直认为其实应该差不多,因为无论如何索引最后都需要被维护,只不过是个时间顺序先后的问题 ...
- SQL Server通过创建临时表遍历更新数据
前言: 前段时间新项目上线为了赶进度很多模块的功能都没有经过详细的测试导致了生成环境中的数据和实际数据对不上,因此需要自己手写一个数据库脚本来更新下之前的数据.(线上数据库用是SQL Server20 ...
- SpringBoot2.x服务器端主动推送技术
一.服务端推送常用技术介绍 服务端主流推送技术:websocket.SSE等 1.客户端轮询:ajax定时拉取后台数据 js setInterval定时函数 + ajax异步加载 定时向服务 ...
- 【SpringBoot】服务器端主动推送SSE技术讲解
=====================16.高级篇幅之SpringBoot2.0服务器端主动推送SSE技术讲解 ============================ 1.服务端推送常用技术介绍 ...
- 织梦CMS5.7主动推送二次开发
今天一个朋友叫我写个织梦的百度主动推送插件,实现的功能是:每发表或者更新一篇文章,都会触动主动推送,达到资源最新提交给百度进行抓取. 案例站点:奇迹私服 第一步:登入FTP,在/后台的文件夹/arti ...
- server端推送消息机制
推送技术相关请参加WIKI: https://zh.wikipedia.org/wiki/%E6%8E%A8%E9%80%81%E6%8A%80%E6%9C%AF 场景: 监控系统:后台硬件温度.电压 ...
- SQL Server 2008中新增的变更数据捕获(CDC)和更改跟踪
来源:http://www.cnblogs.com/downmoon/archive/2012/04/10/2439462.html 本文主要介绍SQL Server中记录数据变更的四个方法:触发器 ...
- SQL Server 之 在数据库之间进行数据导入导出
1.同一服务器上数据库之间进行数据导入导出 (1).使用 SELECT INTO 导出数据 在SQL Server中使用最广泛的就是通过SELECT INTO语句导出数据,SELECT INTO语句同 ...
随机推荐
- RHCS集群理论暨最佳实践
RHCS集群理论暨 最佳实践 什么是集群? 集群是一组(>2)相互独立的,通过高速网络互联的计算机组成的集合.群集一般可以分为科学集群,负载均衡集群,高可用性集群三大类. 科学集 ...
- linux配置Java(JDK)环境变量
本帖最后由 zhai 于 2013-11-19 23:00 编辑 1.下载jdk Oracle官方下载地址:http://www.oracle.com/technetwork/java/javase/ ...
- C#处理四舍五入的问题
在处理一些数据时,我们希望能用“四舍五入”法实现,但是C#采用的是“四舍六入五成双”的方法,如下面的例子,就是用“四舍六入五成双”得到的结果: double d1 = Math.Round(1.25, ...
- suse linux编译安装GCC报错
gcc编译安装过程 1.先安装三个库 gmp mprc mpc 这三个库的源码要到官网去下载 1)安装gmp:首先建立源码同级目录 gmp-build,输入命令,第一次编译不通过,发现缺少一个叫m4的 ...
- winphone 开发学习笔记(2)
导航 NavigationService.Navigate(new Uri("xxxx.xaml",UriKind.Relative)) xxx表示要跳转的目标页面 页面和页面导航 ...
- Magic of David Copperfield II(奇偶性)
题目大意:这是一个魔术游戏,首先把你的手指放在一个左上角的格子里面,然后魔术师说你可以移动K1步,移动完之后,他会删除一些方格,并且说,你肯定不在这里,删除的方格不可以再去了,然后让你再走K2步,继续 ...
- poj 2631 Roads in the North【树的直径裸题】
Roads in the North Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 2359 Accepted: 115 ...
- 403. Frog Jump
做完了终于可以吃饭了,万岁~ 假设从stone[i]无法跳到stone[i+1]: 可能是,他们之间的距离超过了stone[i]所能跳的最远距离,0 1 3 7, 从3怎么都调不到7: 也可能是,他们 ...
- 基于Centos6.x定制化安装步骤
1.获取安装界面代码 挂载image/install.img:mount image/install.img /mnt/5 -o loop 复制挂载后的代码至self_intall ...
- 深度学习Matlab DeepLearningToolBox 工具包最常见错误解决办法\
deeplearningtoolbox 下载链接github : https://github.com/rasmusbergpalm/DeepLearnToolbox,只需要解压到matlab当前工 ...