MVC SignalR未从Controller Post方法触发

时间:2018-12-17 19:46:09

标签: asp.net-mvc signalr-hub

将日程表保存到日历时,它必须自动更新家庭控制器中通知栏上的活动日志。它保存数据,但仅在刷新通知栏时显示。保存后,似乎集线器无法启动。

CalendarController.cs

       [HttpPost]
        public JsonResult SaveSchedule(Schedule s)
        {
            var userid = User.Identity.GetUserId();
            var profile = _context.Profiles.Single(p => p.Id == userid);
            var status = false;

            if (s.Schedule_ID > 0)
            {
                //Update
                var v = _context.Schedules.Where(a => a.Schedule_ID == s.Schedule_ID).FirstOrDefault();
                if (v != null)
                {
                    v.Shift = s.Shift;
                }

            }

            var activitylog = new ActivityLog
            {
                UserId = userid,
                LogDate = DateTime.Now,
                Activity = ActivityHelper.GetActivityLog(4, profile.FirstName)

            };
             // save to data and must be shown on notification bar
            _context.ActivityLogs.Add(activitylog);
            _context.SaveChanges();
            ActivityHub.StartLogging();
            status = true;
            return new JsonResult { Data = new { status = status } };
        }

HomeController.cs

public JsonResult GetLogs()
        {
            return Json(ActivityHelper.GetActivityLogs(), JsonRequestBehavior.AllowGet);
        }

ActivityHub.cs

 public class ActivityHub : Hub
    {
        public static void StartLogging()
        {
            IHubContext context = GlobalHost.ConnectionManager.GetHubContext<ActivityHub>();

            //calls the signalR client part to execute javascript method
            context.Clients.All.displayLog();
        }
    }

我的CSHTML

<script>
    $(function () {
   var activityFromHub = $.connection.activityHub;
        $.connection.hub.start().done(function () {
            FetchLogs();
        });

        activityFromHub.client.displayLog = function () {
            console.log('Hub Started');
            FetchLogs();
        }

function FetchLogs() {

            $.ajax({
                type: 'GET',
                url: '/Home/GetLogs',
                datatype: 'json',
                success: function (data) {
                    $("#logs tr").remove();
                    data = $.parseJSON(data);
                    if (data.length > 0) {
                           .... do some append here
                    }
                },
                error: function (error) {
                    alert("error");
                }
            });
        }
});
</script>

ActivityHelper.cs

static readonly string connString = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;

public static class ActivityHelper
    {
            public static string GetActivityLogs()
            {
                string sqlCommand = @"my select query here";
                try
                {
                    var messages = new List<ActivityLog>();
                    using(var connection = new SqlConnection(connString))
                    {
                        connection.Open();
                        using (SqlConnection con = new SqlConnection(connString))
                        {
                            SqlCommand cmd = new SqlCommand(sqlCommand, con);
                            if(con.State != System.Data.ConnectionState.Open)
                            {
                                con.Open();
                            }
                            cmd.Notification = null;
                            SqlDependency dependency = new SqlDependency(cmd);
                            dependency.OnChange += new OnChangeEventHandler(dependency_OnChange);

                            var reader = cmd.ExecuteReader();

                            while (reader.Read())
                            {
                                messages.Add(item: new ActivityLog
                                {
                                    Activity = reader["Activity"] != DBNull.Value ? (string)reader["Activity"] : "",
                                    LogDate = (DateTime)reader["LogDate"]
                                });
                            }
                        }
                    }
                    var jsonSerialiser = new JavaScriptSerializer();
                    var json = jsonSerialiser.Serialize(messages);
                    return json;

                }
                catch(Exception ex)
                {
                    throw;
                }
            }



public static void dependency_OnChange(object sender, SqlNotificationEventArgs e)
        {
            if (e.Type == SqlNotificationType.Change)
            {
                SqlDependency dependency = sender as SqlDependency;
                dependency.OnChange -= dependency_OnChange;

                var activityHub = GlobalHost.ConnectionManager.GetHubContext<ActivityHub>();
                GetActivityLogs();
            }
        }

}

1 个答案:

答案 0 :(得分:0)

第一种方法 第一个解决方案是这样更改您的JavaScript代码。如果这样做不起作用,请转到第二种方法:

 $(function () {
   var activityFromHub = $.connection.ActivityHub;
        $.connection.hub.start().done(function () {
            FetchLogs();
        });

        activityFromHub.client.displayLog = function () {
            console.log('Hub Started');
            FetchLogs();
        }
});

第二种方法:

每个连接到集线器的客户端都传递一个唯一的连接ID。您可以在中心上下文的Context.ConnectionId属性中检索此值。我发现没有发生这样的事情。您可以尝试此解决方案。

我认为您问题的最简单解决方案是使用组。 http://www.asp.net/signalr/overview/guide-to-the-api/working-with-groups

您的中心类将包含加入组的方法:

public Task JoinGroup(string groupName)
{
    return Groups.Add(Context.ConnectionId, groupName);
}

public Task LeaveGroup(string groupName)
{
    return Groups.Remove(Context.ConnectionId, groupName);
}

您的集线器将如下所示:

public static void StartLogging(string groupName)
{
   IHubContext context = GlobalHost.ConnectionManager.GetHubContext<ActivityHub>();
   context.Clients.Group(groupName).displayLog();

   //calls the signalR client part to execute javascript method
   //context.Clients.All.displayLog();
}

并像这样更改您的JavaScript:

$(function () {
   var activityFromHub = $.connection.ActivityHub;
        $.connection.hub.start().done(function () {
            activityFromHub.server.joinGroup("Group1");
            activityFromHub.server.StartLogging("Group1");
            FetchLogs();
        });

        activityFromHub.client.displayLog = function () {
            console.log('Hub Started');
            FetchLogs();
        }
});

我希望这可以解决您的问题。如果您仍然面临问题。请发表评论。谢谢。