使用SQL依赖关系的ASP.NET MVC中的SignalR数据库更新通知

时间:2019-01-24 19:26:45

标签: c# sql asp.net signalr

我使用SQL Server Service Broker设置了一个signalR ASP.NET MVC应用程序示例。我在使用本教程 https://www.codeproject.com/articles/874240/signalr-database-update-notifications-in-asp-net-m

我还已将数据库ALTER DATABASE BlogDemos设置为具有ROLLBACK IMMEDIATE的SET ENABLE_BROKER;

我正在使用SQL 2012,它有时通过ENABLE_BROKER称为客户端函数,但并非每次都调用。

我有几个问题:

1)当我更新和更改数据库上的记录时,除非再次运行以下查询,否则客户端站点上什么都不会发生: ALTER DATABASE Your_DB_Name SET ENABLE_BROKER具有ROLLBACK IMMEDIATE; 尽管有时即使运行此查询后,客户端站点上也没有更改。 2)运行上述查询(... ENABLE_BROKER ...)之后,需要花费 10秒 来查看客户端的更改

3)大约10秒钟的延迟后,GetMessages函数被调用了两次。

Hub : 
MessageHubs.cs:

namespace SignalRDbUpdates.Hubs
{
    public class MessagesHub : Hub
    {
        private static string conString = ConfigurationManager.ConnectionStrings["DefaultConnection"].ToString();

        [HubMethodName("sendMessages")]
        public static void SendMessages()
        {
            IHubContext context = GlobalHost.ConnectionManager.GetHubContext<MessagesHub>();
            context.Clients.All.updateMessages();
        }        
    }
}

MessagesRepository.cs

namespace SignalRDbUpdates.Models
{
    public class MessagesRepository
    {
        readonly string _connString = ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString;

        public IEnumerable<Messages> GetAllMessages()
        {
            var messages = new List<Messages>();
            using (var connection = new SqlConnection(_connString))
            {
                connection.Open();
                using (var command = new SqlCommand(@"SELECT [MessageID], [Message], [EmptyMessage], [Date] FROM [dbo].[Messages]", connection))
                {
                    command.Notification = null;

                    var dependency = new SqlDependency(command);
                    dependency.OnChange += new OnChangeEventHandler(dependency_OnChange);

                    if (connection.State == ConnectionState.Closed)
                        connection.Open();

                    var reader = command.ExecuteReader();

                    while (reader.Read())
                    {
                        messages.Add(item: new Messages { MessageID = (int)reader["MessageID"], Message = (string)reader["Message"], EmptyMessage =  reader["EmptyMessage"] != DBNull.Value ? (string) reader["EmptyMessage"] : "", MessageDate = Convert.ToDateTime(reader["Date"]) });
                    }
                }

            }
            return messages;


        }

        private void dependency_OnChange(object sender, SqlNotificationEventArgs e)
        {
            if (e.Type == SqlNotificationType.Change)
            {
                MessagesHub.SendMessages();
            }


        }
    }
}

index.chtml

@{
    ViewBag.Title = "Home Page";
}

<div class="row">
    <div class="col-md-12">
        <div id="messagesTable"></div>
    </div>
</div>
@section Scripts{

    <script src="~/Scripts/jquery.signalR-2.4.0.js"></script>     
    <script src="/signalr/hubs"></script>
    <script type="text/javascript">
        $(function () {            
            var Notifications = $.connection.messagesHub;
            Notifications.client.updateMessages = function () {
                getAllMessages()
                //alert('Updated!')                
            };

            // 
            $.connection.hub.start().done(function () {                
                getAllMessages();
                console.log('connected--started')
            }).fail(function (e) {
                alert(e);
            });
        });


        function getAllMessages() {
            var tbl = $('#messagesTable');
            $.ajax({
                url: '/home/GetMessages',
                contentType: 'application/html ; charset:utf-8',
                type: 'GET',
                async: true,
                dataType: 'html'
            }).success(function (result) {
                tbl.empty().append(result);
                console.log('result......');
                return true
            }).error(function () {
                alert('ERROR!')
            });
        }


    </script>
}

startup.cs

using Microsoft.AspNet.SignalR;
using Microsoft.Owin;
using Owin;
using System.Configuration;

[assembly: OwinStartupAttribute(typeof(SignalRDbUpdates.Startup))]
namespace SignalRDbUpdates
{
    public partial class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            ConfigureAuth(app);
            string connString = ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString;
            app.MapSignalR();   
        }
    }
}

Global.asax

    namespace SignalRDbUpdates
    {
        public class MvcApplication : System.Web.HttpApplication
        {
            string connString = ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString;

            protected void Application_Start()
            {
                AreaRegistration.RegisterAllAreas();
                FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
                RouteConfig.RegisterRoutes(RouteTable.Routes);
                BundleConfig.RegisterBundles(BundleTable.Bundles);
                GlobalConfiguration.Configure(WebApiConfig.Register);           
                //SqlDependency.Start(connString);
                SqlDependency.Start(ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString);
        }

        protected void Application_End()
            {

                //SqlDependency.Stop(connString);
                SqlDependency.Stop(ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString);
            }
        }
    }

0 个答案:

没有答案