Asp.NET MVCのときめき/ロングコネクション
8396 ワード
0 x 01オンラインユーザークラス、私のユーザー一意性はIDとタイプによって識別される(異なる表にあるため)
0 x 02セッション管理、スレッド+辞書
0 x 03コントローラ実装
に注意
1、[SessionState(System.Web.SessionState.SessionState.SessionStateBehavior.ReadOnly)]は必須です.そうしないと、リフレッシュ(繰り返し呼び出し)がロックされ、原理が熟練しているので自分で理解し、初心者がそのようにすればいいです.
2,/admin/api/keepalive呼び出しのActionは自身である.
3、サービス側は要求の解放間隔を制御する.ここに設置されている30 s.1分を超えるとActionタイムアウトが発生する可能性がある場合は、AsyncTimeoutAttributeプロパティを追加して、解放間隔よりもActionタイムアウト時間を設定する必要があります.
0 x 04フロントエンドコード、jQueryが必要です.最初の呼び出しがトリガーされ、サービス側でjsに戻って自動的に実行されます.
コードが簡単だと思いますか?シンプルで実用的で使いやすいことを重視するのはブロガーの一貫した追求である.
コピーはソースブログ園、道木さんを明記してください.のNetソフトウェア交流群283590657
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; }
}
0 x 02セッション管理、スレッド+辞書
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);
}
}
}
0 x 03コントローラ実装
[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.SessionState.SessionStateBehavior.ReadOnly)]は必須です.そうしないと、リフレッシュ(繰り返し呼び出し)がロックされ、原理が熟練しているので自分で理解し、初心者がそのようにすればいいです.
2,/admin/api/keepalive呼び出しのActionは自身である.
3、サービス側は要求の解放間隔を制御する.ここに設置されている30 s.1分を超えるとActionタイムアウトが発生する可能性がある場合は、AsyncTimeoutAttributeプロパティを追加して、解放間隔よりもActionタイムアウト時間を設定する必要があります.
0 x 04フロントエンドコード、jQueryが必要です.最初の呼び出しがトリガーされ、サービス側でjsに戻って自動的に実行されます.
$(function () {
//KeepAlive
$.getScript('/admin/api/keepalive');
}
コードが簡単だと思いますか?シンプルで実用的で使いやすいことを重視するのはブロガーの一貫した追求である.
コピーはソースブログ園、道木さんを明記してください.のNetソフトウェア交流群283590657