2013-09-27 5 views
6

세션 구조를 구현 중입니다.세션을 어떻게 처리합니까?

나는 서버 측에 <SessionId, UserSession> 쌍을 모두 보유하고 있습니다 (ConcurrentDictionary).

새 연결이 설정되면 RememberMe 옵션에 따라 쿠키가 클라이언트 브라우저 perm 또는 temp에 할당됩니다.

클라이언트가 LogOut 함수를 호출하면 사전에서 세션이 제거됩니다.

그러나 클라이언트 브라우저가 단순히 닫히거나 손상되고 쿠키가 손실되거나 만료되거나 삭제되면 메모리의 서버 쪽 세션 개체가 사전에 남아 고스트가됩니다. 시간이 지남에 따라 이러한 유령이 쌓일 것입니다.

내 질문은 만료 된 후에 죽은 세션을 정리할 수 있도록 디자인을 개선하는 방법입니다.

나는 타이머 서비스를 청소 스케줄로 실행하는 것에 대해 생각했지만 우아하지는 않습니다. 외부 서비스에 의존하지 않고 이것을 수행하는 간단한 방법이 있습니까?

+1

롤링 기간이있는 캐시를 사용하거나 Session_End 메서드를 처리하는 것이 좋습니다. UserSession에 무엇을 저장하고 있습니까? – zimdanen

+0

처리 할 신뢰할 수있는 Session_End 메소드가 없습니다. 클라이언트 브라우저가 충돌하면 서버로 다시 이야기하지 않고 거기에서 끝납니다. 하지만 캐시를 언급 했으므로 생각이났습니다. LastActive 시간순으로 정렬 된 목록을 저장할 수 있습니다. 새로운 클라이언트가 로그인 할 때마다 대기열에서 가장 이른 세션을 확인하고 만료되면 제거 할 수 있습니다. 모든 활성 사용자는 서버를 호출하여 작업을 수행 할 때 자신을 대기열의 맨 뒤로 가져갑니다. 그래서, 그는 가장 활동적인 사람이됩니다. – Tom

+0

로그인 한 모든 사람에 대한 데이터를 어느 시점에서보아야합니까? 그렇지 않다면 세션에 데이터를 저장하고 세션이 종료 된 후에 데이터를 사라지게하십시오. 그것은 압력이있는 경우 세션에서 항목을 삭제하여 메모리 압력도 처리합니다. 또는 롤링 타임 아웃과 함께 HttpContext.Cache를 사용하면 마지막 액세스 이후 설정된 시간이 지나면 사라집니다. (기본적으로 자신의 것을 굴릴 필요가 없습니다.) – zimdanen

답변

4

나는 나의 프로젝트 중 하나에서 비슷한 상황이있다. 에, 내가, 아약스 호출, 15 초마다 할

HttpContext.Current.Cache.Insert(sessionID, userEntity, null, DateTime.Now.AddSeconds(30), TimeSpan.Zero); 

및 클라이언트 측에 대신 사전

, 내 캐시 키로 사용자의 짧은 절대 만료 및 세션 ID로 캐시를 사용 서버에 알리고 해당 세션 ID에 대한 캐시를 갱신하십시오.

사용자가 브라우저 창을 닫을 때마다 서버는 사용자의 알림 및 세션 ID를 자동으로 만료하지 않습니다.

+0

고마워요, 아이디어를 따라 몇 가지 검색 않았다 깨달은 System.Runtime.Caching 위의 .NET4 갈 방법입니다 것 같습니다. http://bartwullems.blogspot.com.au/2011/02/caching-in-net-4.html – Tom

0

몇 달 후 내 자신의 질문에 대답하고 있습니다. 그런 구조를 원한다면 Microsoft SignalR을 사용할 것입니다. 그것은 나를 위해 세션을 실시간 방식으로 제어하고 훨씬 더 많은 일을하기 때문입니다.

+0

여전히 사용자를 인증하는 데 Sessions를 사용하고있는 이유는 무엇입니까? 이 방법은 고전 ASP 시대에 대한 실행 가능한 솔루션 이었지만 더 이상은 아닙니다. 대신 ASP에서 선호되는 접근 방법 인'ASP.NET Forms authentication'을 사용하는 것을 고려해야합니다.NET World. – VahidN

2

세션 상태가 "InProc"인 경우 Session_Start 및 Session_End에 코드를 적용하지 않는 이유는 무엇입니까?

void Session_Start(object sender, EventArgs e) 
{ 
    //Add to ConcurrentDictionary 
} 

void Session_End(object sender, EventArgs e) 
{ 
    // Note: The Session_End event is raised only when the sessionstate mode 
    // is set to InProc in the Web.config file. If session mode is set to StateServer 
    // or SQLServer, the event is not raised. 

    //Remove from ConcurrentDictionary 
}