1

I am hesitating while posting this question, as there are number of answers available on net for same But my bad luck, nothing is helping me out. For my web application i need notification part and for that i thought using SignalR 2 in same.

But its not working. Below is the complete code parts:

==>Hub Class

[HubName("MyHub")]
public class MyHub : Hub
{
    public static void Show()
    {
        IHubContext context = GlobalHost.ConnectionManager.GetHubContext<MyHub>();
        context.Clients.All.displayStatus();
    }
}

==>Global File

public class MvcApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        SqlDependency.Start(ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString);
        AreaRegistration.RegisterAllAreas();
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);
    }

    protected void Application_End()
    {
        SqlDependency.Stop(ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString);
    }
}

==>Repository

public class DAL
{
    public List<DTO.Employee> GetEmployee()
    {
        List<DTO.Employee> l = new List<DTO.Employee>();
        try
        {
            using (var con = new SqlConnection(ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString))
            {
                con.Open();
                using (var cmd = new SqlCommand("select * from employee", con))
                {
                    cmd.Notification = null;
                    SqlDependency dep = new SqlDependency(cmd);
                    dep.OnChange += new OnChangeEventHandler(Dep_OnChange);

                    using (var drd = cmd.ExecuteReader())
                    {
                        while (drd.Read())
                        {
                            l.Add(new DTO.Employee()
                            {
                                Id = Convert.ToInt64(drd["id"]),
                                Name = Convert.ToString(drd["name"])
                            });
                        }
                    }
                }
            }
        }
        catch { }
        return l;
    }

    private void Dep_OnChange(object sender, SqlNotificationEventArgs e)
    {
        if (e.Type == SqlNotificationType.Change)
        {
            MyHub.Show();
        }
    }
}

==> Owin Startup Class

[assembly: OwinStartupAttribute(typeof(SignalR2_App1.Startup))]

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

==> View

<script src="~/Scripts/jquery-1.10.2.min.js"></script>    
<script src="~/Scripts/jquery.signalR-2.2.0.min.js"></script>
<script src="~/signalr/hubs"></script>
<script type="text/javascript">
    $(function () {
        var job = $.connection.MyHub;
        job.client.displayStatus = function () {
            getData();
        }
        $.connection.hub.start();
        getData();
    })
    function getData() {
        $.ajax({
            url: "/data/getdata",
            contentType: "application/json charset=utf-8",
            dataType: "json",
            type: "Post",
            success: function (result) {
                $.each(result, function (e, obj) {
                    $("#tbldata_tbody").append("<tr><td>" + obj.Id + "</td><td>" + obj.Name + "</td></tr>")
                })
            },
            error: function () {
                alert("Error");
            }
        })
    }
</script>
<body>
<table id="tbldata">
    <thead>
        <tr>
            <td>Id</td>
            <td>Name</td>
        </tr>
    </thead>
    <tbody id="tbldata_tbody"></tbody>
</table>

==>Action

[HttpPost]
    public JsonResult GetData()
    {
        DAL.DAL O = new DAL.DAL();
        return Json(O.GetEmployee());
    }

You can download the whole code from below link:
Code Link

ArjunArora
  • 986
  • 3
  • 12
  • 27
  • I have also checked [link](https://learn.microsoft.com/en-us/aspnet/signalr/overview/testing-and-debugging/troubleshooting#connection). On Sql Server i have run this query: ALTER DATABASE SignalRDemo SET ENABLE_BROKER WITH ROLLBACK IMMEDIATE; – ArjunArora Mar 01 '18 at 06:00
  • Also i have debug my code and found that Dep_OnChange event is not getting fired upon any change in table. Why? – ArjunArora Mar 01 '18 at 06:02
  • Solution: 1. This code was working fine in chrome but not in mozila firefox. So there was no issue in code. 2. Later it was noticed that parameter SqlNotificationEventArgs e in method Dep_OnChange was always bringing **Subscribe** as value. 3. So it was clear that there was something missing from sql server side. 4. At last i found that i skipped `GRANT SUBSCRIBE QUERY NOTIFICATIONS To sa` 5. Running previous query was throwing error : `Cannot find the user 'sa', because it does not exist or you do not have permission.` 6. Then we change it to public instead of sa and it was fine. – ArjunArora Mar 05 '18 at 12:00
  • I finally found the article which helped me out [link](https://www.codeproject.com/Articles/144344/Query-Notification-using-SqlDependency-and-SqlCach) – ArjunArora Mar 05 '18 at 12:09

1 Answers1

1

According your code I think that you do not understand all details of signalr. Here are some hints:

1. Inside your hub you do not need GlobalHost.ConnectionsManager

Inside the hub you have already a Clients property

2. Do not create an instance of you hub by yourself!

Inside you DAL you should not call

  MyHub.Show();

Instead grap HubContext:

GlobalHost.ConnectionManager.GetHubContext<MyHub>().Clients.All.displayStatus();

Better approach - Use Strongly-Types-Hubs:

According your code I think that you do not understand all details of signalr. I suggest you to read https://learn.microsoft.com/en-us/aspnet/signalr/overview/guide-to-the-api/hubs-api-guide-server

For example on the hub you should only define the methods which the clients can call on the server. For proper definition of the methods which the server can call on the clients you can use "Strongly-Types-Hubs". See: https://learn.microsoft.com/en-us/aspnet/signalr/overview/guide-to-the-api/hubs-api-guide-server#stronglytypedhubs

Background information about Hub object lifetime:

https://learn.microsoft.com/en-us/aspnet/signalr/overview/guide-to-the-api/hubs-api-guide-server:

You don't instantiate the Hub class or call its methods from your own code on the server; all that is done for you by the SignalR Hubs pipeline. SignalR creates a new instance of your Hub class each time it needs to handle a Hub operation such as when a client connects, disconnects, or makes a method call to the server.

Because instances of the Hub class are transient, you can't use them to maintain state from one method call to the next. Each time the server receives a method call from a client, a new instance of your Hub class processes the message. To maintain state through multiple connections and method calls, use some other method such as a database, or a static variable on the Hub class, or a different class that does not derive from Hub. If you persist data in memory, using a method such as a static variable on the Hub class, the data will be lost when the app domain recycles.

If you want to send messages to clients from your own code that runs outside the Hub class, you can't do it by instantiating a Hub class instance, but you can do it by getting a reference to the SignalR context object for your Hub class. For more information, see How to call client methods and manage groups from outside the Hub class later in this topic.

Stephu
  • 3,236
  • 4
  • 21
  • 33
  • 1
    Thanks for sharing such great links. It will surely help in improving or gaining complete info regarding SignalR. Btw the changes you suggested did not worked. There were few couples of things which were discovered and finally got the success. Will share those in this thread soon. – ArjunArora Mar 05 '18 at 08:51
  • @Arjun It's clear that I wrote not a complete solution because there where a lot of mistakes. My answers where only to put you on the right way.:-). So the answer my not be correct but I thinks it helped you a lot.... – Stephu Mar 05 '18 at 08:54
  • Yes off-course, even not only me but to anyone who will read this ques. Thanks buddy. – ArjunArora Mar 05 '18 at 10:59