首页 > Web开发 > 详细

Asp.NET MVC 之心跳/长连接

时间:2016-01-30 02:32:52      阅读:550      评论:0      收藏:0      [点我收藏+]

0x01 在线用户类,我的用户唯一性由ID和类型识别(因为在不同的表里)

public class UserIdentity : IEqualityComparer<UserIdentity>
    {
        internal UserIdentity() { }
        public UserIdentity(int userId, int userType)
        {
            this.UserID = userId;
            this.UserType = userType;
        }
        public int UserID { get; private set; }
        public int UserType { get; private set; }

        public bool Equals(UserIdentity x, UserIdentity y)
        {
            return x.UserID == y.UserID && x.UserType == y.UserType;
        }

        public int GetHashCode(UserIdentity obj)
        {
            return obj.UserID * (obj.UserType + 10);
        }
    }
    public class AliveUser
    {
        private AliveUser() { }
        public AliveUser(string sessionID, int userID, int userType)
        {
            this.SessionID = sessionID;
            this.StartAt = DateTime.Now;
            this.User = new UserIdentity(userID, userType);
        }

        public void SetExpires(DateTime expires)
        {
            this.Expires = expires;
        }
        public string SessionID { get; private set; }
        public DateTime StartAt { get; private set; }
        public DateTime Expires { get; private set; }
        public UserIdentity User { get; private set; }
    }

    

0x02 会话管理,线程+字典

public class AliveSessionHelper
    {
        static AliveSessionHelper()
        {
            thread.IsBackground = true;
            thread.Start();
        }
        public static int TimeoutInMinutes = 1;
        private static object syncObject = new object();
        public static Dictionary<string, AliveUser> OnlineUsers = new Dictionary<string, AliveUser>();
        public static Dictionary<UserIdentity, List<AliveUser>> GetOnlineUsers()
        {
            lock (syncObject)
            {
                var list = OnlineUsers.Values.ToList();
                var grouping = list.GroupBy(x => x.User,new UserIdentity());
                var dict = new Dictionary<UserIdentity, List<AliveUser>>(grouping.Count());
                foreach (var item in grouping)
                {
                    dict.Add(item.Key, item.ToList());
                }
                return dict;
            }
        }

        public static void AddAliveUser(string sessionID, int userID, int userType)
        {
            AddAliveUser(new AliveUser(sessionID, userID, userType));
        }

        public static void AddAliveUser(AliveUser user)
        {

            lock (syncObject)
            {
                var aliveUser = OnlineUsers.ContainsKey(user.SessionID) ? OnlineUsers[user.SessionID] : null;
                if (aliveUser == null)
                {
                    OnlineUsers.Add(user.SessionID, user);
                }

                var expires = DateTime.Now.AddMinutes(TimeoutInMinutes);
                OnlineUsers[user.SessionID].SetExpires(expires);
            }
        }

        private static Thread thread = new Thread(ThreadStartBody);
        private static void ThreadStartBody()
        {
            while (true)
            {
                lock (syncObject)
                {
                    var delList = new List<Guid>();
                    var list = OnlineUsers.Values.ToList();
                    foreach (var item in list)
                    {
                        if (item.Expires.Subtract(DateTime.Now).TotalSeconds < 5)
                        {
                            OnlineUsers.Remove(item.SessionID);
                        }
                    }
                }
                Thread.Sleep(29);
            }
        }
    }

  

0x03 控制器实现

[SessionState(System.Web.SessionState.SessionStateBehavior.ReadOnly)]
    [Authorize]
    public class ApiController : AsyncController
    {
        public async Task<ActionResult> KeepAlive()
        {
            if (!User.Identity.IsAuthenticated) {
                return null;
            }
            AliveSessionHelper.AddAliveUser(Session.SessionID, AdminUserService.Instance.CurrentUserID, 0);
            return await Task.Delay(TimeSpan.FromSeconds(30)).ContinueWith(task =>
            {
                return JavaScript("$.getScript(‘/admin/api/keepalive‘);");
            });
        }
    }    

  注意

1、[SessionState(System.Web.SessionState.SessionStateBehavior.ReadOnly)]是必须的,否则刷新(重复调用)会锁死,原理熟手自己领会,新手照做即可。

2、/admin/api/keepalive 调用Action的是自身。

 

0x04 前端代码,需要jQuery。原生js本人不会,请自行搞定。

$(function () {
         //KeepAlive
         $.getScript(‘/admin/api/keepalive‘);
}

  

是不是感觉代码很简单?拷贝请注明来源博客园,作者孤独飞鸿

QQ625761566 

.Net软件交流群283590657

  

Asp.NET MVC 之心跳/长连接

原文:http://www.cnblogs.com/mrtiny/p/5170286.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!