jubi
jubi

Reputation: 625

How to call multiple hub method from SignalR

I am using SignalR and MVC.

I have developed an admin page where I can send notifications. There is a menu with an icon to display the unread notification.

If I click on the count a notification panel will display with the latest 5 notifications.

There is also a "View All" link which opens a new page to show all the notifications. If admin add new notification, I want to update the notification count as well as the view "All notification" page.

How can I call both the hub method on admin send button? I am expecting to see the newly added Notification in the ViewAllNotification page without refreshing. Expecting SignalR to push the data.

I have followed http://venkatbaggu.com/signalr-database-update-notifications-asp-net-mvc-usiing-sql-dependency/ for my development.

Here i am not using sql dependency. On Send button(Admin screen) i am calling the hub methods to push notification

    <script type="text/javascript">
        $(function () {
            $.connection.hub.logging = true;
            var proxy = $.connection.broadcastMessage;

            $.connection.hub.start().done(function () {
                $('#button1').click(function () {
                    proxy.server.broadcastNotifications($("#Message").val());
                    proxy.server.sendMessages();
                });
            });
        });
    </script>

This is the Hub method.

    public class BroadcastMessage: Hub
        {
        public void BroadcastNotifications(string message)
        {         
            Utility.AddNotification(message);

            int UnreadCount = Utility.getUnreadMessageCount();

            IHubContext context = GlobalHost.ConnectionManager.GetHubContext<BroadcastMessage>();
            context.Clients.All.receiveNotification(message, UnreadCount);
        }

        public static void SendMessages()
        {
            IHubContext context = GlobalHost.ConnectionManager.GetHubContext<BroadcastMessage>();
            context.Clients.All.updateMessages();
        }
    }

I have tried the above jQuery and signal r to call method one by one. But this doesn't work. It calls the first method and the second one didn't get invoked.

@model IEnumerable<Notification>
@{
    Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>ViewAllNotifications</h2>
<div class="container">
<table class="table">
    <tr>
        <th>@Html.DisplayNameFor(model => model.NotificationID)</th>
        <th>
            @Html.DisplayNameFor(model => model.Message)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.CreatedBy)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.CreatedDate)
        </th>

    </tr>

@foreach (var item in Model) {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.NotificationID)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Message)
        </td>
        <th>
            @Html.DisplayFor(modelItem => item.CreatedBy)
        </th>
        <td>
            @Html.DisplayFor(modelItem => item.CreatedDate)
        </td>

    </tr>
}

</table>

</div>
<script type="text/javascript">

        $(function () {
            debugger;
            $.connection.hub.logging = true;
            var proxy = $.connection.broadcastMessage;

            proxy .client.updateMessages = function () {
                getAllMessages()
            };
            $.connection.hub.start().done(function () {
                alert("connection started")

                getAllMessages();
            }).fail(function (e) {
                alert(e);
            });
            function getAllMessages() {
                var tbl = $('#messagesTable');

                $.ajax({
                    url: '/Notifications/GetMessages',
                    cache: false,
                    contentType: 'application/html ; charset:utf-8',
                    type: 'GET',
                    dataType: 'html'
                }).success(function (result) {
                    tbl.empty().append(result);
                }).error(function () {

                });
            }

        });
</script>

Above is the partial view.And i was referring to http://venkatbaggu.com/signalr-database-update-notifications-asp-net-mvc-usiing-sql-dependency/ My req is to push notification to this page whenever admin send notifications.

Upvotes: 2

Views: 4973

Answers (2)

Glenn Ferrie
Glenn Ferrie

Reputation: 10390

You should chain the calls, one after another, like this:

$.connection.hub.start().done(function () {
        $('#button1').click(function () {
            proxy.server.broadcastNotifications($("#Message").val()).done(function () {
                proxy.server.sendMessages();
            });        
        });
    });

UPDATE

Referring to my comment below, you will need to add some code to your ViewAllNotifications View to allow SignalR to refresh it. You are presently rendering the data on the server-side, so SignalR won't cause a reload.

you can try this, but I would recommend you rethink your approach like @Tez described.

<script type="text/javascript">
    $(function () {
        $.connection.hub.logging = true;
        var proxy = $.connection.broadcastMessage;

        proxy.client.updateMessages = function () {
            location.reload();
            // reload the page from the server
        };

        $.connection.hub.start();   
    });
</script>

Upvotes: 0

Tez Wingfield
Tez Wingfield

Reputation: 2251

This is on the assumption that all dependencies are in the same process, If so you do not need GetHubContext

You should reorganise the logic like so:

Hub

[HubName("messageHub")]
public class MessageHub: Hub
{
    public void BroadcastNotifications(string message)
    {         
        Utility.AddNotification(message);
        int UnreadCount = Utility.getUnreadMessageCount();
        Clients.All.receiveNotification(message, UnreadCount);

        SendMessages();
    }

    public void SendMessages()
    {
        Clients.All.updateMessages();
    }
}

JS

<script type="text/javascript">
    $(function () {
        $.connection.hub.logging = true;
        var messageHub = $.connection.messageHub;

        $.connection.hub.start().done(function () {
            $('#button1').click(function () {
                messageHub.server.broadcastNotifications($("#Message").val());
            });
        });
    });
</script>

Upvotes: 1

Related Questions