保持ASP.NET会话开放/活跃

Ale*_*lex 111 c# asp.net session

只要用户打开浏览器窗口,哪种最简单,最不显眼的方式可以使ASP.NET会话保持活动状态?是时候调用AJAX吗?我想阻止以下情况:有时候用户长时间打开窗口,然后输入内容,并且提交时不再有效,因为服务器端会话已过期.我不希望在服务器上增加超过10分钟的超时值,因为我希望关闭会话(通过关闭浏览器窗口)快速超时.

建议,代码示例?

veg*_*rby 167

我使用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"
    );
}
Run Code Online (Sandbox Code Playgroud)

会话处理程序可以简单如下:

public class SessionHeartbeatHttpHandler : IHttpHandler, IRequiresSessionState
{
    public bool IsReusable { get { return false; } }

    public void ProcessRequest(HttpContext context)
    {
        context.Session["Heartbeat"] = DateTime.Now;
    }
}
Run Code Online (Sandbox Code Playgroud)

关键是添加IRequiresSessionState,否则Session将不可用(= null).如果某些数据应该返回给调用JavaScript,那么处理程序当然也可以返回JSON序列化对象.

通过web.config提供:

<httpHandlers>
    <add verb="GET,HEAD" path="SessionHeartbeat.ashx" validate="false" type="SessionHeartbeatHttpHandler"/>
</httpHandlers>
Run Code Online (Sandbox Code Playgroud)

于2012年8月14日从balexandre 添加

我非常喜欢这个例子,我想用HTML/CSS和节拍部分来改进

改变这一点

//$("#heartbeat").show().fadeOut(1000); // just a little "red flash" in the corner :)
Run Code Online (Sandbox Code Playgroud)

beatHeart(2); // just a little "red flash" in the corner :)
Run Code Online (Sandbox Code Playgroud)

并添加

// 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);
}
Run Code Online (Sandbox Code Playgroud)

HTML和CSS

<div class="heartbeat">&hearts;</div>

/* HEARBEAT */
.heartbeat {
    position: absolute;
    display: none;
    margin: 5px;
    color: red;
    right: 0;
    top: 0;
}
Run Code Online (Sandbox Code Playgroud)

这里只是跳动部分的实例:http://jsbin.com/ibagob/1/

  • +1和+ acc用于代码的良好解决方案. (2认同)
  • 不错的工作,但直到我在通话中添加了缓存突发,它才对我失败.如果没有此缓存突发参数,则首次调用控制器 (2认同)
  • @stom _meant_ 是一个会话值,而不是超时或任何东西。使用`DateTime.Now` 的原因只是为了使会话最后一次通过心跳更新的时间一目了然。 (2认同)

小智 65

如果您使用的是ASP.NET MVC,则不需要额外的HTTP处理程序和web.config文件的一些修改.所有你需要的 - 只需在Home/Common控制器中添加一些简单的动作:

[HttpPost]
public JsonResult KeepSessionAlive() {
    return new JsonResult {Data = "Success"};
}
Run Code Online (Sandbox Code Playgroud)

,编写一段像这样的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();
}
Run Code Online (Sandbox Code Playgroud)

,并通过调用JavaScript函数初始化此功能:

SetupSessionUpdater('/Home/KeepSessionAlive');
Run Code Online (Sandbox Code Playgroud)

请注意!我已经仅为授权用户实现了此功能(在大多数情况下没有理由为访客保留会话状态)并且保持会话状态活动的决定不仅基于 - 浏览器是否打开,但授权用户必须执行某些活动在网站上(移动鼠标或键入一些键).

  • 对于MVC,我认为这是更好的答案.不需要使用.ashx文件,你为什么要这样做? (3认同)
  • Maryan,您可能还想在初始化函数中使用`@Ull.Action("KeepSessionAlive","Home")`,这样您就不必对URL进行硬编码,也可以将第一个块抛出到IIFE中并导出`SetupSessionUpdater`,因为这是唯一需要在外部调用的东西 - 如下所示:[SessionUpdater.js](https://gist.github.com/KyleMit/aa4f576fa32bf36fbedab5540c18211d#file-sessionupdater-js) (2认同)

Bor*_*ode 8

每当您向服务器发出请求时,会话超时都会重置.因此,您只需对服务器上的空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();
        }
    }
Run Code Online (Sandbox Code Playgroud)

.JS:

window.onload = function () {
        setInterval("KeepSessionAlive()", 60000)
}

 function KeepSessionAlive() {
 url = "/KeepSessionAlive.ashx?";
        var xmlHttp = new XMLHttpRequest();
        xmlHttp.open("GET", url, true);
        xmlHttp.send();
        }
Run Code Online (Sandbox Code Playgroud)

@veggerby - 不需要在会话中存储变量的开销.只需向服务器执行请求就足够了.