MVC SignalR не запускается из метода Controller Post - PullRequest
0 голосов
/ 17 декабря 2018

При сохранении расписания в календарь оно должно автоматически обновлять журналы активности на панели уведомлений в моем домашнем контроллере.Данные сохраняются, но отображаются только при обновлении панели уведомлений.Похоже, что концентратор не запускается при сохранении.

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 голосов
/ 13 января 2019

ПЕРВЫЙ МЕТОД Первое решение измените свой код JavaScript следующим образом.Если это не работает, перейдите ко второму способу:

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

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

ВТОРОЙ МЕТОД:

Каждый клиент, подключающийся к концентратору, передает уникальный идентификатор соединения.Вы можете получить это значение в свойстве 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();
        }
});

Я надеюсь, что это решит вашу проблему.Если вы все еще сталкиваетесь с проблемой.Пожалуйста, оставляйте комментарии.Спасибо.

...