ASP.NET SignalR-With Database

1. 创建数据库SignalR,并启用Broker:

ALTER DATABASE SignalR SET ENABLE_BROKER

2.在Global.asax中:

 protected void Application_Start(object sender, EventArgs e)
        {
            System.Data.SqlClient.SqlDependency.Start(ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString);
        }
  protected void Application_End(object sender, EventArgs e)
        {
            System.Data.SqlClient.SqlDependency.Stop(ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString);
        }

3.在Startup.cs中:

  public void Configuration(IAppBuilder app)
        {
            app.MapSignalR();
        }
4.NotificationHub.cs:

[HubName("notificationHub")]
public class NotificationHub : Hub
{
    private static readonly ConcurrentDictionary<string, User> Users = new ConcurrentDictionary<string, User>(StringComparer.InvariantCultureIgnoreCase);

    #region Methods
    /// <summary>
    /// Provides the handler for SignalR OnConnected event
    /// supports async threading
    /// </summary>
    /// <returns></returns>
    public override Task OnConnected()
    {
        string profileId = "111"; //Context.QueryString["id"];
        string connectionId = Context.ConnectionId;
        var user = Users.GetOrAdd(profileId, _ => new User
        {
            ProfileId = profileId,
            ConnectionIds = new HashSet<string>()
        });
        lock (user.ConnectionIds)
        {
            user.ConnectionIds.Add(connectionId);
            Groups.Add(connectionId, user.ProfileId);
        }
        return base.OnConnected();
    }
    /// <summary>
    /// Provides the handler for SignalR OnDisconnected event
    /// supports async threading
    /// </summary>
    /// <returns></returns>
    public override Task OnDisconnected(bool stopCalled)
    {
        string profileId = Context.QueryString["id"];
        string connectionId = Context.ConnectionId;
        User user;
        Users.TryGetValue(profileId, out user);
        if (user != null)
        {
            lock (user.ConnectionIds)
            {
                user.ConnectionIds.RemoveWhere(cid => cid.Equals(connectionId));
                Groups.Remove(connectionId, user.ProfileId);
                if (!user.ConnectionIds.Any())
                {
                    User removedUser;
                    Users.TryRemove(profileId, out removedUser);
                }
            }
        }
        return base.OnDisconnected(stopCalled);
    }

    /// <summary>
    /// Provides the handler for SignalR OnReconnected event
    /// supports async threading
    /// </summary>
    /// <returns></returns>
    public override Task OnReconnected()
    {
        return base.OnReconnected();
    }

    /// <summary>
    /// Provides the facility to send individual user notification message
    /// </summary>
    /// <param name="profileId">
    /// Set to the ProfileId of user who will receive the notification
    /// </param>
    /// <param name="message">
    /// set to the notification message
    /// </param>
    public void Send(string profileId, string message)
    {
        //Clients.User(profileId).send(message);
    }

    /// <summary>
    /// Provides the facility to send group notification message
    /// </summary>
    /// <param name="username">
    /// set to the user groupd name who will receive the message
    /// </param>
    /// <param name="message">
    /// set to the notification message
    /// </param>
    public void SendUserMessage(String username, String message)
    {
        Clients.Group(username).sendUserMessage(message);
    }

    /// <summary>
    /// Provides the ability to get User from the dictionary for passed in profileId
    /// </summary>
    /// <param name="profileId">
    /// set to the profileId of user that need to be fetched from the dictionary
    /// </param>
    /// <returns>
    /// return User object if found otherwise returns null
    /// </returns>
    private User GetUser(string profileId)
    {
        User user;
        Users.TryGetValue(profileId, out user);
        return user;
    }

    /// <summary>
    /// Provide theability to get currently connected user
    /// </summary>
    /// <returns>
    /// profileId of user based on current connectionId
    /// </returns>
    public IEnumerable<string> GetConnectedUser()
    {
        return Users.Where(x =>
        {
            lock (x.Value.ConnectionIds)
            {
                return !x.Value.ConnectionIds.Contains(Context.ConnectionId, StringComparer.InvariantCultureIgnoreCase);
            }
        }).Select(x => x.Key);
    }
    #endregion

    private Notificator _notificator;
    public NotificationHub()
    {
        _notificator = Notificator.Instance;
    }
    public void SendNotifications()
    {
        _notificator.QueryNotifications();
    }
}
Notificator.cs:

public class Notificator
    {
        private readonly static Lazy<Notificator> _instance = new Lazy<Notificator>(()=> new Notificator (GlobalHost.ConnectionManager.GetHubContext<NotificationHub>().Clients));
        private IHubConnectionContext<dynamic> Clients { get; set; }
        private Notificator(IHubConnectionContext<dynamic> clients)
        {
            this.Clients = clients;
        }
        public static Notificator Instance
        {
            get { return _instance.Value; }
        }
        Int16 totalNewMessages = 0;
        Int16 totalNewCircles = 0;
        Int16 totalNewJobs = 0;
        Int16 totalNewNotification = 0;

        [HubMethodName("sendNotifications")]
        public void QueryNotifications()
        {
            using (var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString))
            {
                string query = "SELECT  NewMessageCount, NewCircleRequestCount, NewNotificationsCount, NewJobNotificationsCount FROM [dbo].[User] WHERE UserProfileId=" + "62021";
                connection.Open();
                using (SqlCommand command = new SqlCommand(query, connection))
                {
                    try
                    {
                        command.Notification = null;
                        DataTable dt = new DataTable();
                        SqlDependency dependency = new SqlDependency(command);
                        dependency.OnChange += new OnChangeEventHandler(dependency_OnChange);
                        if (connection.State == ConnectionState.Closed)
                            connection.Open();
                        var reader = command.ExecuteReader();
                        dt.Load(reader);
                        if (dt.Rows.Count > 0)
                        {
                            totalNewMessages = Int16.Parse(dt.Rows[0]["NewMessageCount"].ToString());
                            totalNewCircles = Int16.Parse(dt.Rows[0]["NewCircleRequestCount"].ToString());
                            totalNewJobs = Int16.Parse(dt.Rows[0]["NewJobNotificationsCount"].ToString());
                            totalNewNotification = Int16.Parse(dt.Rows[0]["NewNotificationsCount"].ToString());
                        }
                        connection.Close();
                    }
                    catch (Exception ex)
                    {
                        throw;
                    }
                }
            }
            Clients.All.RecieveNotification(totalNewMessages, totalNewCircles, totalNewJobs, totalNewNotification);
        }
        private void dependency_OnChange(object sender, SqlNotificationEventArgs e)
        {
            if (e.Type == SqlNotificationType.Change)
            {
                QueryNotifications();
            }
        }
    }
index.html:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>New Notifications</title>
    <script src="scripts/jquery-1.10.2.min.js"></script>
    <script src="scripts/jquery.signalR-2.1.2.min.js"></script>>        
    <script src="signalr/hubs"></script>
    <script type="text/javascript">
        $(function () {            
            // Declare a proxy to reference the hub.
            var notifications = $.connection.notificationHub;
            debugger;
            // Create a function that the hub can call to broadcast messages.
            notifications.client.recieveNotification = function (totalNewMessages, totalNewCircles, totalNewJobs, totalNewNotifications) {
                // Add the message to the page.                
                $('#spanNewMessages').text(totalNewMessages);
                $('#spanNewCircles').text(totalNewCircles);
                $('#spanNewJobNotifications').text(totalNewJobs);
                $('#spanNewNotifications').text(totalNewNotifications);
            };
            // Start the connection.
            $.connection.hub.start().done(function () {
                notifications.server.sendNotifications();
            }).fail(function (e) {
                alert(e);
            });
            //$.connection.hub.start();            
        });
    </script>
</head>
<body>
    <h1>Broadcast Realtime SQL data using SignalR</h1>
    <div>
        <p>You have <span id="spanNewMessages">0</span> New Message Notification.</p>
        <p>You have <span id="spanNewCircles">0</span> New Circles Notification.</p>
        <p>You have <span id="spanNewJobNotifications">0</span> New Job Notification.</p>
        <p>You have <span id="spanNewNotifications">0</span> New Notification.</p>
    </div>
</body>
</html>


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值