![](/img/trans.png)
[英]How to remain signed in even when the user closes the app in android studio
[英]Scripting events no longer fire when a user leaves site or closes browser even though app is still active
我正在使用的項目從母版頁實現三個JAVA腳本“計時器”,以跟蹤會話超時並進行“心跳”檢查。 如果超時計數達到1分半鍾(會話超時之前),則“ setTimerout”計時器會將用戶重定向到警告頁面。 實現了兩個“ setInterval”計時器來跟蹤用戶的瀏覽器是否在站點上處於活動狀態。 以下是實現“計時器”以及“心跳”和“心跳檢查”處理程序的幾個代碼段。
激活計時器的母版頁代碼:
Dim BaseAccountTimeout As Single = CType((CType(CurrentSessionTimeout, Single) - 1.5), Single)
If Session.Item("UseSessionTimeout") Then
Dim TimeoutAcount As String = CType(((BaseAccountTimeout * 60) * 1000), Integer).ToString
Page.ClientScript.RegisterStartupScript(Me.GetType, "TimeoutScript", "setTimeout(""top.location.href = '" & GotoTimeoutPage & "'""," & TimeoutAcount & ");", True)
End If
If Session.Item("UseHeartBeat") Then
Dim BaseHeartBeatTimeout As Single = CType(CurrentHeartBeatTimeout, Single)
Dim BaseHeartBeatCheckTimeout As Single = CType((BaseHeartBeatTimeout + 1.5), Single)
Dim TimeoutHeartBeat As String = CType(((BaseHeartBeatTimeout * 60) * 1000), Integer).ToString
Dim TimeoutHeartBeatCheck As String = CType(((BaseHeartBeatCheckTimeout * 60) * 1000), Integer).ToString
Page.ClientScript.RegisterStartupScript(Me.GetType, "HeartBeatScript", "setInterval(""ajax.post('/pages/heartbeat.ashx', {id: '" + Session.SessionID + "'}, function() {})""," & TimeoutHeartBeat & ");", True)
Page.ClientScript.RegisterStartupScript(Me.GetType, "HeartBeatCheckScript", "setInterval(""ajax.post('/pages/heartbeatcheck.ashx', {id: '" + Session.SessionID + "'}, function() {})""," & TimeoutHeartBeatCheck & ");", True)
End If
心跳處理程序代碼:
<%@ webhandler language="VB" class="HeartbeatHandler" %>
Imports System
Imports System.Web
Imports System.Data
Imports System.Data.SqlClient
Public Class HeartbeatHandler
Implements IHttpHandler
Public ReadOnly Property IsReusable As Boolean Implements IHttpHandler.IsReusable
Get
Return True
End Get
End Property
Public Sub ProcessRequest(ByVal ctx As HttpContext) Implements IHttpHandler.ProcessRequest
Dim sqlConnection1 As New System.Data.SqlClient.SqlConnection(ConfigurationManager.ConnectionStrings("ApplicationServices").ConnectionString)
Dim cmd As New System.Data.SqlClient.SqlCommand
Dim dreader As System.Data.SqlClient.SqlDataReader
Dim GotOne As Boolean = False
Dim ValuesString As String = ""
Dim FieldsString As String = ""
Dim id As String = ""
id = ctx.Request.Params.Item("id")
If IsNothing(id) Then id = ""
If id = "" Then GoTo EXITHEARTBEAT
cmd.Connection = sqlConnection1
cmd.CommandType = System.Data.CommandType.Text
If cmd.Parameters.Count = 0 Then
cmd.Parameters.Add("@uID", System.Data.SqlDbType.NVarChar)
cmd.Parameters.Add("@Date", System.Data.SqlDbType.DateTime)
cmd.Parameters.Add("@IP", System.Data.SqlDbType.NVarChar)
End If
cmd.Parameters("@uID").Value = id
cmd.Parameters("@Date").Value = CType(Now, DateTime)
cmd.Parameters("@IP").Value = HttpContext.Current.Request.UserHostAddress
Try
cmd.CommandText = "SELECT SessionID FROM aspnet_Sessions WHERE SessionID = @uID"
sqlConnection1.Open()
dreader = cmd.ExecuteReader()
If dreader.Read() Then GotOne = True
dreader.Close()
Catch ex As Exception
' do nothing here
Finally
sqlConnection1.Close()
End Try
If GotOne Then
Try
ValuesString = "LastRequest = @Date"
cmd.CommandText = "UPDATE aspnet_Sessions SET " + ValuesString + " WHERE SessionID = @uID"
sqlConnection1.Open()
cmd.ExecuteNonQuery()
Catch ex As Exception
' do nothing here
Finally
sqlConnection1.Close()
End Try
Else
Try
FieldsString = "(Record, LiveDate, SessionID, LastRequest, IPAddress)"
ValuesString = "(NEWID(), @Date, @uID, @Date, @IP)"
cmd.CommandText = "INSERT aspnet_Sessions " + FieldsString + " VALUES " + ValuesString
sqlConnection1.Open()
cmd.ExecuteNonQuery()
Catch ex As Exception
' do nothing here
Finally
sqlConnection1.Close()
End Try
End If
EXITHEARTBEAT:
End Sub
End Class
心跳檢查處理程序代碼:
<%@ webhandler language="VB" class="HeartbeatCheckHandler" %>
Imports System
Imports System.Web
Imports System.Data
Imports System.Data.SqlClient
Public Class HeartbeatCheckHandler
Implements IHttpHandler
Public ReadOnly Property IsReusable As Boolean Implements IHttpHandler.IsReusable
Get
Return True
End Get
End Property
Public Sub ProcessRequest(ByVal ctx As HttpContext) Implements IHttpHandler.ProcessRequest
Dim sqlConnection1 As New System.Data.SqlClient.SqlConnection(ConfigurationManager.ConnectionStrings("ApplicationServices").ConnectionString)
Dim cmd As New System.Data.SqlClient.SqlCommand
Dim dreader As System.Data.SqlClient.SqlDataReader
Dim GotOne As Boolean = Nothing
Dim ValuesString As String = ""
Dim FieldsString As String = ""
Dim LastRequest As DateTime = Nothing
Dim TimeDifference As Long = 0
Dim HeartBeatTimeout As Single = CommonCode.Common.DefaultHeartBeatTimeout
Dim MissedHeartBeats As Single = CommonCode.Common.DefaultMissedHeartBeats
Dim id As String = ""
id = ctx.Request.Params.Item("id")
If IsNothing(id) Then id = ""
If id = "" Then GoTo EXITHEARTBEATCHECK
cmd.Connection = sqlConnection1
cmd.CommandType = System.Data.CommandType.Text
Try
cmd.CommandText = "SELECT HeartBeatTimeout, MaximumMissedHeartBeats FROM aspnet_WebSiteSettings"
cmd.CommandType = System.Data.CommandType.Text
sqlConnection1.Open()
dreader = cmd.ExecuteReader()
If dreader.Read() Then
HeartBeatTimeout = dreader("HeartBeatTimeout")
MissedHeartBeats = dreader("MaximumMissedHeartBeats")
End If
dreader.Close()
Catch ex As Exception
' do nothing here
Finally
sqlConnection1.Close()
End Try
Dim MaximumDifference As Single = (HeartBeatTimeout * MissedHeartBeats) + 0.5
If cmd.Parameters.Count = 0 Then cmd.Parameters.Add("@uID", System.Data.SqlDbType.NVarChar)
cmd.Parameters("@uID").Value = id
Try
cmd.CommandText = "SELECT SessionID, LastRequest FROM aspnet_Sessions WHERE SessionID = @uID"
cmd.CommandType = System.Data.CommandType.Text
sqlConnection1.Open()
dreader = cmd.ExecuteReader()
If dreader.Read() Then
If Not IsDBNull(dreader("LastRequest")) Then
If dreader("LastRequest").ToString.Trim <> "" Then
LastRequest = dreader("LastRequest")
TimeDifference = DateDiff(DateInterval.Minute, LastRequest, CType(Now, DateTime))
If TimeDifference > MaximumDifference Then GotOne = True
Else
GotOne = False
End If
Else
GotOne = False
End If
Else
GotOne = False
End If
dreader.Close()
Catch ex As Exception
' do nothing here
Finally
sqlConnection1.Close()
End Try
If GotOne Then
Try
cmd.CommandText = "DELETE aspnet_Sessions WHERE SessionID = @uID"
cmd.CommandType = System.Data.CommandType.Text
sqlConnection1.Open()
cmd.ExecuteNonQuery()
Catch ex As Exception
' do nothing here
Finally
sqlConnection1.Close()
End Try
CommonCode.Common.DeleteFromSessionIDCollection(id)
CommonCode.Common.SessionData(CommonCode.Common.DeleteSessionData, id)
CommonCode.Common.DisposeSession()
End If
EXITHEARTBEATCHECK:
End Sub
End Class
以下是“母版”頁面上的代碼:
var ajax = {};
ajax.x = function () {
try {
return new ActiveXObject('Msxml2.XMLHTTP')
} catch (e1) {
try {
return new ActiveXObject('Microsoft.XMLHTTP')
} catch (e2) {
return new XMLHttpRequest()
}
}
};
ajax.send = function (url, callback, method, data, sync) {
var x = ajax.x();
x.open(method, url, sync);
x.onreadystatechange = function () {
if (x.readyState == 4) {
callback(x.responseText)
}
};
if (method == 'POST') {
x.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
}
x.send(data)
};
ajax.get = function (url, data, callback, sync) {
var query = [];
for (var key in data) {
query.push(encodeURIComponent(key) + '=' + encodeURIComponent(data[key]));
}
ajax.send(url + '?' + query.join('&'), callback, 'GET', null, sync)
};
ajax.post = function (url, data, callback, sync) {
var query = [];
for (var key in data) {
query.push(encodeURIComponent(key) + '=' + encodeURIComponent(data[key]));
}
ajax.send(url, callback, 'POST', query.join('&'), sync)
};
我發現JAVA腳本計時器僅在網站上存在瀏覽器時才繼續觸發。 一旦用戶關閉瀏覽器或導航離開站點,即使Web應用程序仍在運行,則會話超時時,文件的唯一事件就是Global.asax中的ASP.NET“ Session_End”事件。 我認為不會觸發“計時器”,這是因為不再加載母版頁,因此母版上的腳本不會被觸發。
我真的不在乎“ setTimeout”計時器,因為如果瀏覽器不再在站點上處於活動狀態,則無需重定向到超時頁面,因此腳本可以保留在“母版”頁面上。 但是,兩個“ setInterval”計時器是我要保持運行的計時器,因此該應用程序可以檢測用戶是否已離開該站點,然后該應用程序可以刪除該會話的會話數據和臨時目錄。
我的問題是:是否有人知道從服務運行這兩個腳本的方法或其他實現這些腳本的方法,以便即使瀏覽器已關閉或已轉到另一個站點,它們也將繼續啟動?
謝謝! 大衛
PS。 背景知識:當應用程序從存儲在SQL數據庫中的值開始時,將設置四個全局變量'CurrentSessionTimeout','CurrentHeartBeatTimeout','DefaultHeartBeatTimeout','DefaultMissedHeartBeats'以及兩個會話變量'UseSessionTimeout'和'UseHeartBeat'。 但是,這兩個處理程序都不使用會話變量,而是直接從全局變量或數據庫中獲取它們需要的任何值,因為會話可能在處理程序觸發之前已經結束,也就是說,如果頁面仍在加載,則可以返回原始狀態。這篇文章的原因。 :)
我得出的結論是,當瀏覽器不在站點上時,沒有辦法觸發事件。 似乎像心跳加速的想法一樣“酷”,沒有一種切實可行的方法可以使ASP.NET應用程序網站正常工作,該網站在頁面生成的Javascripts后面使用代碼。 希望這篇文章對其他正在考慮的人有所幫助,並避免他們浪費時間;)
當前,正在重新編寫應用程序的例程以使用Session_End事件。 當Session_End事件觸發時,會話數據實質上消失了,因此您不能將會話變量用於任何清理例程。 相反,計划是創建一些將在Session_Start事件中設置的全局App_Code變量,然后在Session_End事件中使用它們,以刪除所有不活動的會話數據和臨時目錄。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.