Я так близок к тому, чтобы создать систему push-уведомлений, использующую сигнал, но где-то не получится, помогите - PullRequest
0 голосов
/ 30 сентября 2018

Я хочу создать приложение, которое может уведомлять пользователей, когда что-либо вставляется / обновляется или удаляется в базе данных.

Я использовал Signalr вместе с зависимостью sql, но по-прежнему не получаю никаких уведомлений, когда происходит изменение в базе данных.

Это контроллер:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View();
    }

    public JsonResult GetNotificationContacts()
    {
        var notificationRegisterTime = Session["LastUpdated"] != null ? Convert.ToDateTime(Session["LastUpdated"]) : DateTime.Now;
        NotificationComponent NC = new NotificationComponent();
        var list = NC.GetContacts(notificationRegisterTime);
        //update session here for get only new added contacts (notification)
        Session["LastUpdate"] = DateTime.Now;
        return new JsonResult { Data = list, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
    }
}

Это класс запуска. Cs

namespace PushNotification
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            app.MapSignalR();
        }
    }
}

Это строка подключения в файле web.config

<connectionStrings>
    <add name="sqlConString" connectionString="data source=SHOAIB\SQLEXPRESS;initial catalog=MyPushNotification;integrated security=True;" />
    <add name="MyPushNotificationEntities2" connectionString="metadata=res://*/MyPushNotificationModel.csdl|res://*/MyPushNotificationModel.ssdl|res://*/MyPushNotificationModel.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=shoaib\sqlexpress;initial catalog=MyPushNotification;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework&quot;" providerName="System.Data.EntityClient" />
</connectionStrings>

Это концентратор с именем NotificationHub в моем приложении

namespace PushNotification
{
    public class NotificationHub : Hub
    {
        //public void Hello()
        //{
        //    Clients.All.hello();
        //}
    }
}

Это класс компонента уведомлений

namespace PushNotification
{
    public class NotificationComponent
    {
        //Here we will add a function for register notification (will add sql dependency)
        public void RegisterNotification(DateTime currentTime)
        {
            string conStr = ConfigurationManager.ConnectionStrings["sqlConString"].ConnectionString;
            string sqlCommand = @"SELECT [ContactId],[ContactName],[ContactNo] from [dbo].[Contacts] where [AddedOn] > @AddedOn";
            //you can notice here I have added table name like this [dbo].[Contacts] with [dbo], its mendatory when you use Sql Dependency
            using (SqlConnection con = new SqlConnection(conStr))
            {
                SqlCommand cmd = new SqlCommand(sqlCommand, con);
                cmd.Parameters.AddWithValue("@AddedOn", currentTime);
                if (con.State != System.Data.ConnectionState.Open)
                {
                    con.Open();
                }
                cmd.Notification = null;
                SqlDependency sqlDep = new SqlDependency(cmd);
                sqlDep.OnChange += sqlDep_OnChange;
                //we must have to execute the command here
                using (SqlDataReader reader = cmd.ExecuteReader())
                {
                    // nothing need to add here now
                }
            }
        }

        void sqlDep_OnChange(object sender, SqlNotificationEventArgs e)
        {
            if (e.Type == SqlNotificationType.Change)
            {
                SqlDependency sqlDep = sender as SqlDependency;
                sqlDep.OnChange -= sqlDep_OnChange;

                //from here we will send notification message to client
                var notificationHub = GlobalHost.ConnectionManager.GetHubContext<NotificationHub>();
                notificationHub.Clients.All.notify("added");

                //re-register notification
                RegisterNotification(DateTime.Now);

            }
        }

        public List<Contact> GetContacts(DateTime afterDate)
        {
            using (MyPushNotificationEntities2 dc = new MyPushNotificationEntities2())
            {
                return dc.Contacts.Where(a => a.AddedOn > afterDate).OrderByDescending(a => a.AddedOn).ToList();
            }
        }
    }
}

Я внес изменения в файл global.asax, как показано ниже

namespace PushNotification
{
    public class MvcApplication : System.Web.HttpApplication
    {
        string con = ConfigurationManager.ConnectionStrings["sqlConString"].ConnectionString;
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            //here in Application Start we will start Sql Dependency
            SqlDependency.Start(con);
        }

        protected void Session_Start(object sender, EventArgs e)
        {
            NotificationComponent NC = new NotificationComponent();
            var currentTime = DateTime.Now;
            HttpContext.Current.Session["LastUpdated"] = currentTime;
            NC.RegisterNotification(currentTime);
        }
        protected void Application_End()
        {
            //here we will stop Sql Dependency
            SqlDependency.Stop(con);
        }
    }
}

И, наконец, это файл _layout вместе с изменениями

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>@ViewBag.Title - My ASP.NET Application</title>
<link href="~/Content/Site.css" rel="stylesheet" type="text/css" />
<link href="~/Content/bootstrap.min.css" rel="stylesheet" />
<script src="~/Scripts/modernizr-2.6.2.js"></script>
</head>
<body>
<div class="navbar navbar-inverse navbar-fixed-top">
    <div class="container">
        <div class="navbar-header">  
            <span class="noti glyphicon glyphicon-bell"><span class="count">&nbsp;</span></span>            
            <div class="noti-content">
                <div class="noti-top-arrow"></div>
                <ul id="notiContent"></ul>
            </div>
            <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
            @Html.ActionLink("Application name", "Index", "Home", null, new { @class = "navbar-brand" })
        </div>
        <div class="navbar-collapse collapse">
            <ul class="nav navbar-nav">

            </ul>
        </div>
    </div>
</div>
<div class="container body-content">
    @RenderBody()
    <hr />
    <footer>
        <p>&copy; @DateTime.Now.Year - My ASP.NET Application</p>
    </footer>
</div>
@* Add Jquery Library *@
<script src="~/Scripts/jquery-2.2.3.min.js"></script>
<script src="~/Scripts/jquery.signalR-2.2.0.min.js"></script>
<script src="/signalr/hubs"></script>
<script src="~/Scripts/bootstrap.min.js"></script>
@* Add css  *@
<link href="~/Content/bootstrap.min.css" rel="stylesheet" />
<style type="text/css">
    /*Added css for design notification area, you can design by your self*/
    /* COPY css content from youtube video description*/
    .noti-content{
        position:fixed;
        right:100px;
        background:#e5e5e5;
        border-radius:4px;
        top:47px;
        width:250px;
        display:none;
        border: 1px solid #9E988B;
    }
    ul#notiContent{
        max-height:200px;
        overflow:auto;
        padding:0px;
        margin:0px;
        padding-left:20px;
    }
        ul#notiContent li {
            margin:3px;
            padding:6px;
            background:#fff;
        }

        .noti-top-arrow{
            border-color:transparent;
            border-bottom-color:#F5DEB3;
            border-style:dashed dashed solid;
            border-width: 0 8.5px 8.5px;
            position:absolute;
            right:32px;
            top:-8px;
        }
        span.noti{
            color:#FF2323;
            margin:15px;
            position:fixed;
            right:100px;
            font-size:18px;
            cursor:pointer;
        }
        span.count{
            position:relative;
            top:-3px;
        }
</style>

@* Add jquery code for Get Notification & setup signalr *@
<script type="text/javascript">
    $(function () {
        // Click on notification icon for show notification
        $('span.noti').click(function (e) {
            e.stopPropagation();
            $('.noti-content').show();
            var count = 0;
            count = parseInt($('span.count').html()) || 0;
            //only load notification if not already loaded
            if (count > 0) {
                updateNotification();
            }
            $('span.count', this).html('&nbsp;');
        })
        // hide notifications
        $('html').click(function () {
            $('.noti-content').hide();
        })
        // update notification 
        function updateNotification() {
            $('#notiContent').empty();
            $('#notiContent').append($('<li>Loading...</li>'));

            $.ajax({
                type: 'GET',
                url: '/home/GetNotificationContacts',
                success: function (response) {
                    $('#notiContent').empty();
                    if (response.length  == 0) {
                        $('#notiContent').append($('<li>No data available</li>'));
                    }
                    $.each(response, function (index, value) {
                        $('#notiContent').append($('<li>New contact : ' + value.ContactName + ' (' + value.ContactNo + ') added</li>'));
                    });
                },
                error: function (error) {
                    console.log(error);
                }
            })
        }
        // update notification count
        function updateNotificationCount() {
            var count = 0;
            count = parseInt($('span.count').html()) || 0;
            count++;
            $('span.count').html(count);
        }
        // signalr js code for start hub and send receive notification
        var notificationHub = $.connection.notificationHub;
        $.connection.hub.start().done(function () {
            console.log('Notification hub started');
        });

        //signalr method for push server message to client
        notificationHub.client.notify = function (message) {
            if (message && message.toLowerCase() == "added") {
                updateNotificationCount();
            }
        }

    })
</script>
</body>
</html>

Моя база данных находится в студии управления сервером sql, когда я вставляю новую запись, я не получаю никакого уведомления впередний конец.

Пожалуйста, помогите, если у вас есть опыт в этом отношении.Большое спасибо заранее.

1 Ответ

0 голосов
/ 22 июля 2019

Вы должны открыть сервисный брокер

ALTER DATABASE [yourdatabasename] SET ENABLE_BROKER WITH ROLLBACK IMMEDIATE ;

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...