0

FIXED: Code updated that now works.

Trying to setup a websocket for a management dashboard where I need queries using count_big() fields and GROUP BY clauses. Standard recordset lists work great, but once I add the count_big() the websocket doesn't stop sending data. I have read this post about limitations and count_big() appears OK to use. TIA

    using Microsoft.Web.WebSockets;
    using System;
    using System.Collections.Generic;
    using System.Configuration;
    using System.Data;
    using System.Data.SqlClient;
    using System.Linq;
    using System.Net;
    using System.Net.Http;
    using System.Web;
    using System.Web.Http;

    namespace DatabaseChangeNotification.Controllers

{
    public class DatabaseNotificationController : ApiController
    {
        public HttpResponseMessage Get()
        {
            HttpContext.Current.AcceptWebSocketRequest(new ChatWebSocketHandler());
            return Request.CreateResponse(HttpStatusCode.SwitchingProtocols);
        }

        class ChatWebSocketHandler : Microsoft.Web.WebSockets.WebSocketHandler
        {

            public string wsData = null;
            public SqlCommand gblCommand = null;

            public ChatWebSocketHandler()
            {
                SetupNotifier();
            }

            protected void SetupNotifier()
            {
                 using (var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString))
                {
                    connection.Open();
                    // DO NOT USE any "*" in queries
                    // WHen using count the variable was converted to string.  Got Data flood
                    // 
                    // Testing count_big data type
                    //  getString failed
                    //
                     using (SqlCommand command = new SqlCommand(@"select [address], count_big(*) as [CurrentTotal] from dbo.users where address = 'main st' group by address", connection)) 
                    {
                        command.Notification = null;
                        SqlDependency dependency = new SqlDependency(command);
                        dependency.OnChange += new OnChangeEventHandler(dependency_OnChange);
                        if (connection.State == ConnectionState.Closed)
                        {
                            connection.Open();
                        }
                        //SqlCommand gblCommand = command;
                        wsData = null;
                        using (SqlDataReader reader = command.ExecuteReader())
                        {
                            while (reader.Read())
                            {

                                /* MUST MATCH column count and column data type */

                                // wsData += reader.GetString(0) + " " + reader.GetString(1) + " " + reader.GetString(2);

                                /* THIS WORKS FOR GETTING NUMERIC VARIABLES */
                                 wsData += reader.GetValue(0) + " " + int.Parse(reader.GetValue(1).ToString());

                                // wsData += reader.GetString(0) + "</br>";  //works but we get data flood and no numbers


                            }
                            // reader.Close();
                        }
                        _chatClients.Broadcast("data: " + wsData);

                    }
                }
            } //SetupNotifier

            private static WebSocketCollection _chatClients = new WebSocketCollection();

            public override void OnOpen()
            {
                _chatClients.Add(this);
            } // OnOpen

            public override void OnMessage(string msg)
            {
             } // OnMessage

            private void dependency_OnChange(object sender, SqlNotificationEventArgs e)
            {

             if (e.Type != SqlNotificationType.Change)
            {
                _chatClients.Broadcast("Returning, not a change notification ");
                return;
            }

               /*
                * Must remove dependency. Only works once.
                */
                SqlDependency dependency = sender as SqlDependency;
                dependency.OnChange -= dependency_OnChange;

                 //reset for next message.
                 SetupNotifier();

            } // dependency_OnChange
        } // ChatWebSocketHandler

    } // DatabaseNotificationController
}

NOTE: This was happening before code was fixed.

Web Socket returns infinite listing:
    data: main st 1
    data: main st 1
    data: main st 1
    data: main st 1
    data: main st 1
    data: main st 1
    data: main st 1
    data: main st 1
    data: main st 1
    data: main st 1
    data: main st 1
    data: main st 1
    data: main st 1
    data: main st 1
    data: main st 1
    data: main st 1
    data: main st 1
    data: main st 1
    { .....}
Community
  • 1
  • 1
Jim
  • 1,966
  • 3
  • 24
  • 33

1 Answers1

2

You must check the SqlNotificationEventArgs members. Not all notifications indicate a update. Some notifications (like the ones you're getting) indicate invalid conditions or invalid query. You are getting a notification for invalid query and resubmit, just to be immediately notified for the same reason. Ad-nauseam.

Inspecting the notification would point toward the problem. In your case the problem is listed in the very first bullet point in the link yourself posted:

table names must be qualified with two-part names

Remus Rusanu
  • 288,378
  • 40
  • 442
  • 569
  • SqlNotificationEventArgs: info: Invalid source: Statement Any ideas what is wrong? i changed the table name to dbo.users and it didn't help. select dbo.users.address, count_big(dbo.users.address) as [CurrentTotal] from dbo.users where dbo.users.address = 'main st' group by dbo.users.address – Jim Aug 10 '15 at 15:40
  • FIXED: Remus, thanks for pointing me in the right direction. The final query that work was: select [address], count_big() as [CurrentTotal] from dbo.users where [address] = 'main st' group by [address] Notice changing the count_big() to count_big(*), and GODB.DBO.Users to DBO.users. ALSO added if (e.Type != SqlNotificationType.Change) { _chatClients.Broadcast("Returning, not a change notification "); return; } to dependency_OnChange() function – Jim Aug 10 '15 at 18:50