会话丢失时触发客户端事件

时间:2021-03-18 03:49:10

As some of you probably know, Facebook is using this kind of "system" where a popup is displayed when a user session is lost due to inactivity or distant session close. I already saw and read this Node.js question but didn't find anything.

正如你们中的一些人可能知道的那样,Facebook正在使用这种“系统”,当用户会话由于不活动或远程会话关闭而丢失时会显示弹出窗口。我已经看到并阅读了这个Node.js问题,但没有找到任何东西。

I am working for a Canadian computer business our main product is a CRM and everything is coded using Classic ASP.

我在加拿大的一家计算机公司工作,我们的主要产品是CRM,所有东西都是用经典ASP编码的。

I know.

The whole web-based application is working great and since we host the site on our servers, it is possible if necessary to open ports and use sockets.

整个基于Web的应用程序运行良好,因为我们在服务器上托管该站点,所以可以在必要时打开端口并使用套接字。

Here goes the main question: is there a way (using a javascript library or a jQuery plug-in maybe?) to trigger a client-side event when the session expires or is simply lost due to a server reset for example?

这里有一个主要问题:有没有办法(使用javascript库或jQuery插件?)在会话到期时触发客户端事件,或者由于服务器重置而丢失?

Of course, the best would be to use another solution than sending an AJAX request every second to validate if the user session still exists. If it can help, there is a maximum of about 3'500 users connected at the same time and our servers can easily handle more traffic. The servers are working on Windows Server 2008 along with IIS 7.

当然,最好的方法是使用另一种解决方案,而不是每秒发送一次AJAX请求来验证用户会话是否仍然存在。如果它可以提供帮助,同时最多可以连接约3,500个用户,我们的服务器可以轻松处理更多流量。这些服务器与IIS 7一起在Windows Server 2008上运行。

Unfortunately, I cannot provide any code blocks or screenshots for this question since there is nothing to debug.

不幸的是,我无法为此问题提供任何代码块或屏幕截图,因为无需调试。

One idea would be to use an AJAX request to a file that does not return anything and hangs there. If session is lost (inactivity or server reset), the AJAX request will trigger an error and the "error" function will be triggered. Would that be something to consider?

一个想法是对一个不返回任何内容的文件使用AJAX请求并挂起。如果会话丢失(不活动或服务器重置),AJAX请求将触发错误并触发“错误”功能。这会是需要考虑的吗?

Or else, any other suggestions?

或者,还有其他建议吗?

4 个解决方案

#1


3  

One way to do it is to set client-side timer set to the same time as session expiration time.

一种方法是将客户端计时器设置为与会话到期时间相同的时间。

Let's say your session is set to expire after 20 minutes. When page loads - client-side timer set to 20 minutes kicks in. If user does any server interaction (submits form etc.) - timer is reset. But if nothing happens during this 20 minutes - timer counts down and you get your event.

假设您的会话将在20分钟后过期。页面加载时 - 客户端计时器设置为20分钟。如果用户进行任何服务器交互(提交表单等) - 重置计时器。但如果在这20分钟内没有任何反应 - 计时器倒计时,你就会得到你的活动。

#2


3  

You could do the following to achieve this, assuming you have a default session timeout of 20:00 minutes:

假设您的默认会话超时为20:00分钟,您可以执行以下操作来实现此目的:

  1. Ensure, that each user has a "session cookie" issued by you, NOT the default ASP Session Cookie.

    确保每个用户都有一个“会话cookie”,而不是默认的ASP会话Cookie。

    dim live_session_id
    live_session_id = Request.Cookies("livesession")
    if live_session_id = "" then
        live_session_id = create_unique_session_id()
        Response.Cookies("livesession") = live_session_id
    end if
    
  2. Save this live_session_id in a database along with the expected session expire date

    将此live_session_id与预期的会话过期日期一起保存在数据库中

    call updateSession(live_session_id, dateadd("n", 20, now())) ' = now()+20min
    
  3. Output the live_session_id somewhere on your page, so you can access it via JS.

    在页面的某处输出live_session_id,以便您可以通过JS访问它。

  4. Implement a serverside ASP script that checks the current session state for a given live_session_id and make it accessible in IIS in a DIFFERENT subdomain, so calls to this check will NOT refresh the ASP session. The script could return the time difference between now and session end, so you could output the duration the session will remain valid.

    实现一个服务器端ASP脚本,该脚本检查给定live_session_id的当前会话状态,并使其可以在IIS中的不同子域中访问,因此调用此检查不会刷新ASP会话。该脚本可以返回now和session end之间的时间差,因此您可以输出会话保持有效的持续时间。

  5. Add some AJAX code to call the check script every other second, so you could issue a warning if the session time draws to an end.

    添加一些AJAX代码每隔一秒调用一次检查脚本,因此如果会话时间结束,您可以发出警告。

  6. To make it detect IIS reset, you could clear the saved sessions in the database by implementing Application_OnStart in global.asa. This way, your clients would detect a session loss by IIS reset.

    要使其检测IIS重置,您可以通过在global.asa中实现Application_OnStart来清除数据库中保存的会话。这样,您的客户端将通过IIS重置检测到会话丢失。

another quick and dirty method

On every page load, you could let a javascript count down from 20:00 minutes and display a session lost warning after this time. This is what my online banking system uses... :)

在每次加载页面时,您可以让javascript从20:00分钟开始倒计时,并在此时间后显示会话丢失警告。这是我的网上银行系统使用的...... :)

#3


1  

as far as i understand you the main Problem is that the user has to fill out enormous forms. that could take some time and during that time the session could expire.

据我所知,主要问题是用户必须填写巨大的表格。这可能需要一些时间,在此期间会议可能会到期。

furthermore the session could be ended by anything else (iisreset or so) during the time the user fills out the form.

此外,在用户填写表单期间,会话可以通过其他任何内容(iisreset左右)结束。

in my understanding you do not have to notify the Client that the session is lost/expired/ended/abandoned. it would be enough to just show a Login form (Ajax or something) when the user submits the form OR the next request (by Ajax as you mentioned) is made by the Client.

根据我的理解,您不必通知客户会话丢失/过期/结束/放弃。只需在用户提交表单时显示一个Login表单(Ajax或其他内容),或者客户端发出下一个请求(通过Ajax,如您所述)。

the called asp script checks if the session is valid and if not a popup or overlay is shown to Login the user by Ajax first and the form is submitted afterwards.

被调用的asp脚本检查会话是否有效,如果没有,则显示弹出窗口或叠加层,首先通过Ajax登录用户,然后提交表单。

you could think of a http Status code 401 or something to send back to the Client and the Client then Shows the mentioned Ajax Login form...

你可以想到一个http状态代码401或者什么东西发送回客户端然后客户端显示提到的Ajax登录表单......

#4


0  

What makes a session expire in your CRM? Expiring after X time passes since last [user] action is pretty conventional and will allow you to use ajax to keep the session alive. Let's say a session is good for 5 minutes as part of security requirements for super-secret NSA banking CRM with kittens and youtube videos . A good scenario of how a session can be extended would be this:

什么使会话在您的CRM中过期?自上次[用户]操作后经过X时间后过期非常传统,并允许您使用ajax来保持会话处于活动状态。让我们说一个会话是好的5分钟,作为超级秘密NSA银行CRM与小猫和YouTube视频的安全要求的一部分。如何扩展会话的一个好方案是:

  1. a page is opened, validating the session for another 5 minutes
  2. 页面打开,再验证会话5分钟

  3. a timeout is set with JS to make an ajax request every 4 minutes
  4. 使用JS设置超时,每4分钟发出一次ajax请求

  5. [4 minutes later] the request is made, returning a very light-weight response.
  6. [4分钟后]提出请求,返回一个非常轻量级的响应。

  7. if the response says everything is ok and the session is still valid, schedule another "ping" and carry on as usual. If the response comes back with an error (session invalidated on the server because of logging in from a different PC etc.), gracefully handle it. Allow the users to retain what they were working, don't just kick them out to a log in screen with an error
  8. 如果响应说一切正常并且会话仍然有效,请安排另一个“ping”并继续照常进行。如果响应返回错误(由于从其他PC等登录,服务器上的会话无效),请正常处理它。允许用户保留他们正在工作的内容,不要只是将他们带到登录屏幕并显示错误

  9. User navigates away from the page (clicks a link, submits a form), repeat from the beginning. If the user navigates to an external site or closes the browser, his session will self-destruct in no more than 5 minutes :)
  10. 用户导航离开页面(单击链接,提交表单),从头开始重复。如果用户导航到外部站点或关闭浏览器,他的会话将在不超过5分钟内自毁:)

Obviously you can piggy-back any additional information onto the ajax call in step 3 - e.g. notifying the user of new items assigned to them in CRM?

显然,您可以在步骤3中将任何其他信息存储到ajax调用中 - 例如通知用户在CRM中分配给他们的新项目?

Google is your friend, one of the first results gives a not bad overview of the approach basics.

谷歌是你的朋友,最早的结果之一给出了方法基础的不错概述。

#1


3  

One way to do it is to set client-side timer set to the same time as session expiration time.

一种方法是将客户端计时器设置为与会话到期时间相同的时间。

Let's say your session is set to expire after 20 minutes. When page loads - client-side timer set to 20 minutes kicks in. If user does any server interaction (submits form etc.) - timer is reset. But if nothing happens during this 20 minutes - timer counts down and you get your event.

假设您的会话将在20分钟后过期。页面加载时 - 客户端计时器设置为20分钟。如果用户进行任何服务器交互(提交表单等) - 重置计时器。但如果在这20分钟内没有任何反应 - 计时器倒计时,你就会得到你的活动。

#2


3  

You could do the following to achieve this, assuming you have a default session timeout of 20:00 minutes:

假设您的默认会话超时为20:00分钟,您可以执行以下操作来实现此目的:

  1. Ensure, that each user has a "session cookie" issued by you, NOT the default ASP Session Cookie.

    确保每个用户都有一个“会话cookie”,而不是默认的ASP会话Cookie。

    dim live_session_id
    live_session_id = Request.Cookies("livesession")
    if live_session_id = "" then
        live_session_id = create_unique_session_id()
        Response.Cookies("livesession") = live_session_id
    end if
    
  2. Save this live_session_id in a database along with the expected session expire date

    将此live_session_id与预期的会话过期日期一起保存在数据库中

    call updateSession(live_session_id, dateadd("n", 20, now())) ' = now()+20min
    
  3. Output the live_session_id somewhere on your page, so you can access it via JS.

    在页面的某处输出live_session_id,以便您可以通过JS访问它。

  4. Implement a serverside ASP script that checks the current session state for a given live_session_id and make it accessible in IIS in a DIFFERENT subdomain, so calls to this check will NOT refresh the ASP session. The script could return the time difference between now and session end, so you could output the duration the session will remain valid.

    实现一个服务器端ASP脚本,该脚本检查给定live_session_id的当前会话状态,并使其可以在IIS中的不同子域中访问,因此调用此检查不会刷新ASP会话。该脚本可以返回now和session end之间的时间差,因此您可以输出会话保持有效的持续时间。

  5. Add some AJAX code to call the check script every other second, so you could issue a warning if the session time draws to an end.

    添加一些AJAX代码每隔一秒调用一次检查脚本,因此如果会话时间结束,您可以发出警告。

  6. To make it detect IIS reset, you could clear the saved sessions in the database by implementing Application_OnStart in global.asa. This way, your clients would detect a session loss by IIS reset.

    要使其检测IIS重置,您可以通过在global.asa中实现Application_OnStart来清除数据库中保存的会话。这样,您的客户端将通过IIS重置检测到会话丢失。

another quick and dirty method

On every page load, you could let a javascript count down from 20:00 minutes and display a session lost warning after this time. This is what my online banking system uses... :)

在每次加载页面时,您可以让javascript从20:00分钟开始倒计时,并在此时间后显示会话丢失警告。这是我的网上银行系统使用的...... :)

#3


1  

as far as i understand you the main Problem is that the user has to fill out enormous forms. that could take some time and during that time the session could expire.

据我所知,主要问题是用户必须填写巨大的表格。这可能需要一些时间,在此期间会议可能会到期。

furthermore the session could be ended by anything else (iisreset or so) during the time the user fills out the form.

此外,在用户填写表单期间,会话可以通过其他任何内容(iisreset左右)结束。

in my understanding you do not have to notify the Client that the session is lost/expired/ended/abandoned. it would be enough to just show a Login form (Ajax or something) when the user submits the form OR the next request (by Ajax as you mentioned) is made by the Client.

根据我的理解,您不必通知客户会话丢失/过期/结束/放弃。只需在用户提交表单时显示一个Login表单(Ajax或其他内容),或者客户端发出下一个请求(通过Ajax,如您所述)。

the called asp script checks if the session is valid and if not a popup or overlay is shown to Login the user by Ajax first and the form is submitted afterwards.

被调用的asp脚本检查会话是否有效,如果没有,则显示弹出窗口或叠加层,首先通过Ajax登录用户,然后提交表单。

you could think of a http Status code 401 or something to send back to the Client and the Client then Shows the mentioned Ajax Login form...

你可以想到一个http状态代码401或者什么东西发送回客户端然后客户端显示提到的Ajax登录表单......

#4


0  

What makes a session expire in your CRM? Expiring after X time passes since last [user] action is pretty conventional and will allow you to use ajax to keep the session alive. Let's say a session is good for 5 minutes as part of security requirements for super-secret NSA banking CRM with kittens and youtube videos . A good scenario of how a session can be extended would be this:

什么使会话在您的CRM中过期?自上次[用户]操作后经过X时间后过期非常传统,并允许您使用ajax来保持会话处于活动状态。让我们说一个会话是好的5分钟,作为超级秘密NSA银行CRM与小猫和YouTube视频的安全要求的一部分。如何扩展会话的一个好方案是:

  1. a page is opened, validating the session for another 5 minutes
  2. 页面打开,再验证会话5分钟

  3. a timeout is set with JS to make an ajax request every 4 minutes
  4. 使用JS设置超时,每4分钟发出一次ajax请求

  5. [4 minutes later] the request is made, returning a very light-weight response.
  6. [4分钟后]提出请求,返回一个非常轻量级的响应。

  7. if the response says everything is ok and the session is still valid, schedule another "ping" and carry on as usual. If the response comes back with an error (session invalidated on the server because of logging in from a different PC etc.), gracefully handle it. Allow the users to retain what they were working, don't just kick them out to a log in screen with an error
  8. 如果响应说一切正常并且会话仍然有效,请安排另一个“ping”并继续照常进行。如果响应返回错误(由于从其他PC等登录,服务器上的会话无效),请正常处理它。允许用户保留他们正在工作的内容,不要只是将他们带到登录屏幕并显示错误

  9. User navigates away from the page (clicks a link, submits a form), repeat from the beginning. If the user navigates to an external site or closes the browser, his session will self-destruct in no more than 5 minutes :)
  10. 用户导航离开页面(单击链接,提交表单),从头开始重复。如果用户导航到外部站点或关闭浏览器,他的会话将在不超过5分钟内自毁:)

Obviously you can piggy-back any additional information onto the ajax call in step 3 - e.g. notifying the user of new items assigned to them in CRM?

显然,您可以在步骤3中将任何其他信息存储到ajax调用中 - 例如通知用户在CRM中分配给他们的新项目?

Google is your friend, one of the first results gives a not bad overview of the approach basics.

谷歌是你的朋友,最早的结果之一给出了方法基础的不错概述。