qq_36826830 2020-10-24 10:19 采纳率: 0%
浏览 216

asp.net/signalr+sqldependency 消息实时推送,页面刷新导致推送多次?

signalr前后端分离模式
1、客户端
js引入:

<script src="/scripts/jquery-1.6.4.min.js"></script>
<script src="/scripts/jquery.signalR-2.4.1.js"></script>
<script src='http://localhost:25152/SignalR/hubs'></script>

主要代码:

        $.connection.hub.url = "http://localhost:25152/signalr";
    var a;
    $(function () {

        //引用自动生成的代理,myHub是HubName注解属性
        var myHub = $.connection.myHub;

        //后端调用前端
        myHub.client.gg = function () {
            getdata();
            //test();
        };
        //开始连接
        $.connection.hub.start().done(function () {
            getdata();
        })
    });
    function getdata()
    {
        $.ajax({
            type: 'POST',
            url: 'http://localhost:25152/Default/Get',
            dataType: 'json',
            success:function(result)
            {
               console.log(result)
            }
        })
    }

2、服务端
2.1MyHub主要代码:

[HubName("myHub")]
public class MyHub:Hub
{
    //前端调用send
    public static void Send()
    {
        IHubContext cont = GlobalHost.ConnectionManager.GetHubContext<MyHub>();
        //在客户端实现此处的gg方法
        cont.Clients.All.gg();
    }
    //当连接hub实例时被调用
    public override Task OnConnected()
    {
        string connId = Context.ConnectionId;
        return base.OnConnected();
    }
    //当失去连接或链接超时时被调用
    public override Task OnDisconnected(bool stopCalled)
    {

        //stopCalled=true时,客户端关闭连接
        //stopCalled=false时,出现链接超时
        return base.OnDisconnected(stopCalled);
    }

    //重新连接时被调用
    public override Task OnReconnected()
    {
        return base.OnReconnected();
    }
}

2.2Startup主要代码:

app.UseCors(CorsOptions.AllowAll);//跨域访问
app.MapSignalR();//启动SignalR

2.3控制器Default主要代码:

 public JsonResult Get()
    {
        Table tab = new Table();
        var mod = tab.Get();
        return Json(mod, JsonRequestBehavior.AllowGet);
    }

2.4Table类主要代码(从数据库中监听数据变化)

 public IEnumerable<Models.test> Get()
    {
        using (SqlConnection con = new SqlConnection(DB.ConnectionString))
        {
            //此处 要注意 不能使用*  表名要加[dbo]  否则会出现一直调用执行 OnChange
            using (SqlCommand cmd = new SqlCommand("select [id],[name],[paw] from [dbo].[test]", con))
            {
                con.Open();
                cmd.CommandType = CommandType.Text;
                SqlDependency depend = new SqlDependency(cmd);
                //通知事件
                depend.OnChange += new OnChangeEventHandler(depend_onchange);
                //depend.OnChange -= new OnChangeEventHandler(depend_onchange);
                using (SqlDataReader reader = cmd.ExecuteReader())
                {
                    return reader.Cast<IDataRecord>().Select(a => new Models.test()
                    {
                        id = Convert.ToInt32(a["id"]),
                        name = Convert.ToString(a["name"]),
                        paw = Convert.ToString(a["paw"]),
                    }).ToList();

                }
            }
        }
    }
    public void depend_onchange(object sender, SqlNotificationEventArgs e)
    {
        MyHub.Send();
        //通知之后,当前SqlDependency失效,需要重新通知
        SqlDependency dependency = sender as SqlDependency;
        dependency.OnChange -= new OnChangeEventHandler(depend_onchange);
    }

2.5 Global代码就不贴了

目前前后端分离模式代码经测试,可以运行,且能监听数据库变化并将变化的信息推送。但是如果我刷新一次前端网页的话,就会推送2次同样消息,刷新2次,就会推送3次,以此类推叠加,不理解为什么会这样?

  • 写回答

2条回答 默认 最新

  • Json-Huang 2020-10-24 11:17
    关注

    消费端应该没有做幂等处理导致,比如消息进来后先锁定(如消息id),且增加请求消息id是否是相同校验,如果是直接返回;

    评论

报告相同问题?

悬赏问题

  • ¥50 永磁型步进电机PID算法
  • ¥15 sqlite 附加(attach database)加密数据库时,返回26是什么原因呢?
  • ¥88 找成都本地经验丰富懂小程序开发的技术大咖
  • ¥15 如何处理复杂数据表格的除法运算
  • ¥15 如何用stc8h1k08的片子做485数据透传的功能?(关键词-串口)
  • ¥15 有兄弟姐妹会用word插图功能制作类似citespace的图片吗?
  • ¥200 uniapp长期运行卡死问题解决
  • ¥15 latex怎么处理论文引理引用参考文献
  • ¥15 请教:如何用postman调用本地虚拟机区块链接上的合约?
  • ¥15 为什么使用javacv转封装rtsp为rtmp时出现如下问题:[h264 @ 000000004faf7500]no frame?