[c#] ASP.NET 세션을 개방 / 활성 유지
사용자가 브라우저 창을 열어 두는 한 ASP.NET 세션을 유지하는 가장 쉽고 눈에 띄지 않는 방법은 무엇입니까? 정기 AJAX 호출입니까? 다음을 방지하고 싶습니다. 때때로 사용자는 창을 오랫동안 열어 둔 다음 항목을 입력하고 제출할 때 서버 측 세션이 만료 되었기 때문에 더 이상 작동하지 않습니다. 닫힌 세션 (브라우저 창을 닫음)이 빠르게 시간 초과되기를 원하므로 서버에서 10 분 이상 시간 초과 값을 늘리고 싶지 않습니다.
제안, 코드 샘플?
답변
JQuery를 사용하여 세션을 유지하는 것 외에는 아무것도하지 않는 더미 HTTP 핸들러에 대한 간단한 AJAX 호출을 수행합니다.
function setHeartbeat() {
setTimeout("heartbeat()", 5*60*1000); // every 5 min
}
function heartbeat() {
$.get(
"/SessionHeartbeat.ashx",
null,
function(data) {
//$("#heartbeat").show().fadeOut(1000); // just a little "red flash" in the corner :)
setHeartbeat();
},
"json"
);
}
세션 핸들러는 다음과 같이 간단 할 수 있습니다.
public class SessionHeartbeatHttpHandler : IHttpHandler, IRequiresSessionState
{
public bool IsReusable { get { return false; } }
public void ProcessRequest(HttpContext context)
{
context.Session["Heartbeat"] = DateTime.Now;
}
}
핵심은 IRequiresSessionState를 추가하는 것입니다. 그렇지 않으면 세션을 사용할 수 없습니다 (= null). 물론 일부 데이터를 호출하는 JavaScript로 반환해야하는 경우 핸들러는 JSON 직렬화 된 객체를 반환 할 수도 있습니다.
web.config를 통해 제공 :
<httpHandlers>
<add verb="GET,HEAD" path="SessionHeartbeat.ashx" validate="false" type="SessionHeartbeatHttpHandler"/>
</httpHandlers>
추가 로 balexandre 2012 년 8 월 14 일에
이 예제를 너무 좋아해서 HTML / CSS와 비트 부분을 개선하고 싶습니다.
이것을 변경
//$("#heartbeat").show().fadeOut(1000); // just a little "red flash" in the corner :)
으로
beatHeart(2); // just a little "red flash" in the corner :)
추가
// beat the heart
// 'times' (int): nr of times to beat
function beatHeart(times) {
var interval = setInterval(function () {
$(".heartbeat").fadeIn(500, function () {
$(".heartbeat").fadeOut(500);
});
}, 1000); // beat every second
// after n times, let's clear the interval (adding 100ms of safe gap)
setTimeout(function () { clearInterval(interval); }, (1000 * times) + 100);
}
HTML 및 CSS
<div class="heartbeat">♥</div>
/* HEARBEAT */
.heartbeat {
position: absolute;
display: none;
margin: 5px;
color: red;
right: 0;
top: 0;
}
다음은 구타 부분에 대한 실제 예 입니다. http://jsbin.com/ibagob/1/
답변
ASP.NET MVC를 사용하는 경우 추가 HTTP 처리기 및 web.config 파일의 일부 수정이 필요하지 않습니다. 필요한 모든 것 – 홈 / 공통 컨트롤러에 몇 가지 간단한 동작을 추가하기 만하면됩니다.
[HttpPost]
public JsonResult KeepSessionAlive() {
return new JsonResult {Data = "Success"};
}
, 다음과 같은 JavaScript 코드를 작성하십시오 (사이트의 JavaScript 파일 중 하나에 넣었습니다).
var keepSessionAlive = false;
var keepSessionAliveUrl = null;
function SetupSessionUpdater(actionUrl) {
keepSessionAliveUrl = actionUrl;
var container = $("#body");
container.mousemove(function () { keepSessionAlive = true; });
container.keydown(function () { keepSessionAlive = true; });
CheckToKeepSessionAlive();
}
function CheckToKeepSessionAlive() {
setTimeout("KeepSessionAlive()", 5*60*1000);
}
function KeepSessionAlive() {
if (keepSessionAlive && keepSessionAliveUrl != null) {
$.ajax({
type: "POST",
url: keepSessionAliveUrl,
success: function () { keepSessionAlive = false; }
});
}
CheckToKeepSessionAlive();
}
, JavaScript 함수를 호출하여이 기능을 초기화합니다.
SetupSessionUpdater('/Home/KeepSessionAlive');
참고하십시오! 권한이있는 사용자 (대부분의 경우 게스트의 세션 상태를 유지할 이유가 없음)에 대해서만이 기능을 구현했으며 세션 상태를 활성 상태로 유지하기위한 결정은 브라우저가 열려 있는지 여부뿐만 아니라 권한이 부여 된 사용자가 일부 활동을 수행해야합니다. (마우스를 움직이거나 키를 입력).
답변
서버에 요청을 할 때마다 세션 시간 초과가 재설정됩니다. 따라서 서버의 빈 HTTP 핸들러에 ajax 호출을 할 수 있지만 핸들러의 캐시가 비활성화되어 있는지 확인하십시오. 그렇지 않으면 브라우저가 핸들러를 캐시하고 새 요청을 만들지 않습니다.
KeepSessionAlive.ashx.cs
public class KeepSessionAlive : IHttpHandler, IRequiresSessionState
{
public void ProcessRequest(HttpContext context)
{
context.Response.Cache.SetCacheability(HttpCacheability.NoCache);
context.Response.Cache.SetExpires(DateTime.UtcNow.AddMinutes(-1));
context.Response.Cache.SetNoStore();
context.Response.Cache.SetNoServerCaching();
}
}
.JS :
window.onload = function () {
setInterval("KeepSessionAlive()", 60000)
}
function KeepSessionAlive() {
url = "/KeepSessionAlive.ashx?";
var xmlHttp = new XMLHttpRequest();
xmlHttp.open("GET", url, true);
xmlHttp.send();
}
@veggerby-세션에 변수를 저장하는 오버 헤드가 필요하지 않습니다. 서버에 요청을 미리 작성하는 것으로 충분합니다.
답변
세션을 유지해야합니까 (데이터가 있습니까?) 아니면 요청이 들어올 때 세션을 다시 인스턴스화하여이를 위조 할 수 있습니까? 첫 번째 인 경우 위의 방법을 사용하십시오. 두 번째 경우 Session_End 이벤트 처리기를 사용하는 것과 같은 방법을 시도하십시오.
양식 인증이있는 경우 Global.asax.cs에서 다음과 같은 것을 얻을 수 있습니다.
FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(formsCookie.Value);
if (ticket.Expired)
{
Request.Cookies.Remove(FormsAuthentication.FormsCookieName);
FormsAuthentication.SignOut();
...
}
else
{ ...
// renew ticket if old
ticket = FormsAuthentication.RenewTicketIfOld(ticket);
...
}
그리고 세션 수명보다 훨씬 더 긴 티켓 수명을 설정합니다. 인증하지 않거나 다른 인증 방법을 사용하는 경우 유사한 트릭이 있습니다. Microsoft TFS 웹 인터페이스와 SharePoint는 이러한 기능을 사용하는 것 같습니다. 오래된 페이지의 링크를 클릭하면 팝업 창에 인증 프롬프트가 표시되지만 명령 만 사용하면 작동합니다.
답변
이 코드를 자바 스크립트 파일에 작성할 수 있습니다.
$(document).ready(function () {
var delay = (20-1)*60*1000;
window.setInterval(function () {
var url = 'put the url of some Dummy page';
$.get(url);
}, delay);
});
는 (20-1)*60*1000
이 세션 제한 시간을 새로 고쳐집니다, 새로 고침 시간입니다. 새로 고침 시간 제한은 iis = 20 분 중 기본 시간으로 계산됩니다. 즉, 20 × 60000 = 1200000 밀리 초-60000 밀리 초 (세션 만료 1 분 전)가 1140000입니다.
답변
다음은 클라이언트 PC가 절전 모드로 전환되는 경우 살아남 아야하는 대체 솔루션입니다.
로그인 한 사용자가 많으면 서버 메모리를 많이 소모 할 수 있으므로주의해서 사용하십시오.
로그인 후 (로그인 제어의 LoggedIn 이벤트에서 수행)
Dim loggedOutAfterInactivity As Integer = 999 'Minutes
'Keep the session alive as long as the authentication cookie.
Session.Timeout = loggedOutAfterInactivity
'Get the authenticationTicket, decrypt and change timeout and create a new one.
Dim formsAuthenticationTicketCookie As HttpCookie = _
Response.Cookies(FormsAuthentication.FormsCookieName)
Dim ticket As FormsAuthenticationTicket = _
FormsAuthentication.Decrypt(formsAuthenticationTicketCookie.Value)
Dim newTicket As New FormsAuthenticationTicket(
ticket.Version, ticket.Name, ticket.IssueDate,
ticket.IssueDate.AddMinutes(loggedOutAfterInactivity),
ticket.IsPersistent, ticket.UserData)
formsAuthenticationTicketCookie.Value = FormsAuthentication.Encrypt(newTicket)
답변
사용자에게 세션을 갱신하거나 만료 할 수있는 옵션을 제공하는 팝업 대화 상자를 통해 WebForms에서 사용자 세션을 연장하는 방법을 알아 내려고 며칠을 보냈습니다. 알아야 할 # 1은 다른 답변에서 진행되는이 멋진 ‘HttpContext’가 필요하지 않다는 것입니다. 필요한 것은 jQuery의 $ .post (); 방법. 예를 들어 디버깅하는 동안 다음을 사용했습니다.
$.post("http://localhost:5562/Members/Location/Default.aspx");
라이브 사이트에서 다음과 같이 사용합니다.
$.post("http://mysite/Members/Location/Default.aspx");
그것만큼 쉽습니다. 또한 사용자에게 세션을 갱신 할 것인지 묻는 메시지를 표시하려면 다음과 같이하십시오.
<script type="text/javascript">
$(function () {
var t = 9;
var prolongBool = false;
var originURL = document.location.origin;
var expireTime = <%= FormsAuthentication.Timeout.TotalMinutes %>;
// Dialog Counter
var dialogCounter = function() {
setTimeout( function() {
$('#tickVar').text(t);
t--;
if(t <= 0 && prolongBool == false) {
var originURL = document.location.origin;
window.location.replace(originURL + "/timeout.aspx");
return;
}
else if(t <= 0) {
return;
}
dialogCounter();
}, 1000);
}
var refreshDialogTimer = function() {
setTimeout(function() {
$('#timeoutDialog').dialog('open');
}, (expireTime * 1000 * 60 - (10 * 1000)) );
};
refreshDialogTimer();
$('#timeoutDialog').dialog({
title: "Session Expiring!",
autoOpen: false,
height: 170,
width: 350,
modal: true,
buttons: {
'Yes': function () {
prolongBool = true;
$.post("http://localhost:5562/Members/Location/Default.aspx");
refreshDialogTimer();
$(this).dialog("close");
},
Cancel: function () {
var originURL = document.location.origin;
window.location.replace(originURL + "/timeout.aspx");
}
},
open: function() {
prolongBool = false;
$('#tickVar').text(10);
t = 9;
dialogCounter();
}
}); // end timeoutDialog
}); //End page load
</script>
html에 Dialog를 추가하는 것을 잊지 마십시오.
<div id="timeoutDialog" class='modal'>
<form>
<fieldset>
<label for="timeoutDialog">Your session will expire in</label>
<label for="timeoutDialog" id="tickVar">10</label>
<label for="timeoutDialog">seconds, would you like to renew your session?</label>
</fieldset>
</form>
</div>