小谈需求:

最近工作上接到一个需求,做一个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 = UNSAFE
GO
 
--方法名写正确,为程序集中的方法名,注意参数个数
create function WriteStringToFile(@FileFullName as nvarchar(max),  @FileContend AS  nvarchar(max))
returns nvarchar(max)
with returns null on null input
external 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 WriteStringToFile
drop assembly SqlDependency

之后将尝试在web 结合 signal实现实时推送数据给web页面。等待下篇。

sql server主动推送客户端更新数据的更多相关文章

  1. DT7.0主动推送当天高质量图片数据到熊掌号展现

    <?php /* 百度当天主动推送熊掌功能 作者:68喜科技 用于:DT7.0 功能模块:优质内容推送熊掌*出图内容当天推送 */ //引入全局变量函数 defined('IN_DESTOON' ...

  2. SQL Server ->> DISABLE索引后插入更新数据再REBUILD索引 和 保留索引直接插入更新数据的性能差异

    之前对于“DISABLE索引后插入更新数据再REBUILD索引 和 保留索引直接插入更新数据的性能差异”这两种方法一直认为其实应该差不多,因为无论如何索引最后都需要被维护,只不过是个时间顺序先后的问题 ...

  3. SQL Server通过创建临时表遍历更新数据

    前言: 前段时间新项目上线为了赶进度很多模块的功能都没有经过详细的测试导致了生成环境中的数据和实际数据对不上,因此需要自己手写一个数据库脚本来更新下之前的数据.(线上数据库用是SQL Server20 ...

  4. SpringBoot2.x服务器端主动推送技术

    一.服务端推送常用技术介绍 服务端主流推送技术:websocket.SSE等 1.客户端轮询:ajax定时拉取后台数据 js   setInterval定时函数  +  ajax异步加载  定时向服务 ...

  5. 【SpringBoot】服务器端主动推送SSE技术讲解

    =====================16.高级篇幅之SpringBoot2.0服务器端主动推送SSE技术讲解 ============================ 1.服务端推送常用技术介绍 ...

  6. 织梦CMS5.7主动推送二次开发

    今天一个朋友叫我写个织梦的百度主动推送插件,实现的功能是:每发表或者更新一篇文章,都会触动主动推送,达到资源最新提交给百度进行抓取. 案例站点:奇迹私服 第一步:登入FTP,在/后台的文件夹/arti ...

  7. server端推送消息机制

    推送技术相关请参加WIKI: https://zh.wikipedia.org/wiki/%E6%8E%A8%E9%80%81%E6%8A%80%E6%9C%AF 场景: 监控系统:后台硬件温度.电压 ...

  8. SQL Server 2008中新增的变更数据捕获(CDC)和更改跟踪

    来源:http://www.cnblogs.com/downmoon/archive/2012/04/10/2439462.html  本文主要介绍SQL Server中记录数据变更的四个方法:触发器 ...

  9. SQL Server 之 在数据库之间进行数据导入导出

    1.同一服务器上数据库之间进行数据导入导出 (1).使用 SELECT INTO 导出数据 在SQL Server中使用最广泛的就是通过SELECT INTO语句导出数据,SELECT INTO语句同 ...

随机推荐

  1. hadoop单机安装

    1.解压hadoop-1.0.3-bin.tar.gz放到指定目录下. 2.安装java环境,参照文档 3.Ssh无密登录 4.修改conf下四个文件 Hadoop-env.sh: export JA ...

  2. 译文:TransactionScope 与 Async/Await

    你可能不知道这一点,在 .NET Framework 4.5.0  版本中包含有一个关于 System.Transactions.TransactionScope 在与 async/await 一起工 ...

  3. 字符串(后缀自动机):Ahoi2013 差异

    Description Input 一行,一个字符串S Output 一行,一个整数,表示所求值 Sample Input cacao Sample Output 54 HINT 2<=N< ...

  4. HDOJ/HDU 2539 点球大战(String.endsWith()方法的一个应用~)

    Problem Description 在足球比赛中,有不少赛事,例如世界杯淘汰赛和欧洲冠军联赛淘汰赛中,当比赛双方经过正规比赛和加时赛之后仍然不分胜负时,需要进行点球大战来决定谁能够获得最终的胜利. ...

  5. [转载]JVM性能调优--JVM参数配置

    http://www.cnblogs.com/chen77716/archive/2010/06/26/2130807.html

  6. JSP路径的问题

    JSP因为是客户端使用的路径,所以完全可以使用全路径形式 那么在JSP里面使用路径的方式有两种,超链接或者form 当我们在MyEclipse中新建JSP时,可以发现有下面 <%@ page l ...

  7. Linux2.6内核--中断线被关闭的情况

          中断系统是现代操作系统中不可获取的一个子系统,它由硬件主动触发并发送到CPU,最后由内核调用中断处理程序处理中断.       那么中断有时候需要关闭,这是为什么呢?       一般分为 ...

  8. AE 线编辑

    转自原文 AE 线编辑 1.高亮显示节点 //高亮显示节点和端点 public void HighLightNode() { //清空 _mapCtrl.Map.ClearSelection(); _ ...

  9. 在Windows上安装私有GitHub的开源替代-GitLab

    在我之前的一篇博客中介绍过GitLab: 开源免费的git管理工具,今天说一下怎么在windows安装GitLab. BitNami可以很容易的帮助你安装开源应用,和Helicon Zoo类似,我之前 ...

  10. volley使用与解析(一)

    1.什么是volley Volley是google发布的基于Android平台上的网络通信库,能使网络通信更快,更简单,更健壮.获取地址:git clone https://android.googl ...