@mindful just test it with my new system in 2.02 and this /ws/* solution completely disables the purpose of my new system. One can use it they want (or maybe need).
My system works great if you temporary lost your internet connection. It keeps track of all your variables you used on the page and restores them when the connection is back. It does not 'reload' the page if it reconnects (page_ready will not be raised again so you can safely keep using ConnectPage()). This has been tested by 3 people with different connection problems and it looks like it solves all those problems.
The whole purpose of this system is I do NOT want to pass through ABMSessionCreator if event (*1*) (see further) happened.
Mixed with your solution, it always passes through event (*1*). Now I'm getting confused...
------------------------------------------------------------------------------------------------------------------------------
THE CHANGES THAT NEED TO BE DONE IN YOUR PROJECT for 2.02:
------------------------------------------------------------------------------------------------------------------------------
1. In ABMShared
a. Public AppVersion As String = DateTime.now ' NEW 2.01 this helps to get the latest js/css files when the app is started/restarted
b. The new NavigateToPage()
Public Sub NavigateToPage(ws As WebSocket, TargetUrl As String)
If AppVersion <> "" Then
TargetUrl = TargetUrl & "?" & AppVersion
End If
If ws.Open Then
ws.session.SetAttribute("ABMNewSession", True) ' NEW 2.01
ws.Eval("window.location = arguments[0]", Array As Object(TargetUrl))
End If
End Sub
2. In ABMSessionCreator
a. The new Filter()
'Return True to allow the request to proceed.
Public Sub Filter(req As ServletRequest, resp As ServletResponse) As Boolean
DateTime.DateFormat = "dd/MM/yyyy"
DateTime.TimeFormat = "HH:mm"
Log("In filter: " & DateTime.Date(DateTime.Now) & " " & DateTime.Time(DateTime.now))
Dim session As HttpSession = req.GetSession 'a new session will be created if a session doesn't exist.
session.SetAttribute("ABMNewSession", True) ' NEW 2.01
Return True
End Sub
3. In ABMApplication
a. Make sure your Initialize method does NOT load icons that you do not have/use. This causes 404 error.
b. The new Page_ParseEvent()
Sub Page_ParseEvent(Params As Map)
Dim eventName As String = Params.Get("eventname")
Dim eventParams() As String = Regex.Split(",",Params.Get("eventparams"))
If eventName = "beforeunload" Then ' NEW 2.01
Log("preparing for url refresh")
ws.session.SetAttribute("ABMNewSession", True)
Return
End If
If SubExists(Me, eventName) Then
Params.Remove("eventname")
Params.Remove("eventparams")
Select Case Params.Size
Case 0
CallSub(Me, eventName)
Case 1
CallSub2(Me, eventName, Params.Get(eventParams(0)))
Case 2
If Params.get(eventParams(0)) = "abmistable" Then
Dim PassedTables As List = ABM.ProcessTablesFromTargetName(Params.get(eventParams(1)))
CallSub2(Me, eventName, PassedTables)
Else
CallSub3(Me, eventName, Params.Get(eventParams(0)), Params.Get(eventParams(1)))
End If
Case Else
' cannot be called diretly, to many param
CallSub2(Me, eventName, Params)
End Select
End If
End Sub
4. In each of your own pages
a. This is where you have to be focused and see how this fits into your own app! Some explaining:
The
page.SaveSessionVariables(Me, session) and
page.RestoreSessionVariables(Me, session) are very powerful methods. They essentialy keep a reference to all the variables (except WebSockets, ABMPages, ABMaterial) you declared in Class_Globals and are restored in case of a Websocket interruption (like internet temporary lost).
The flow is:
Event (*1*) happened (your page is loaded from the url, the user pressed F5 (refresh) or pressed the refresh button, or you used the NavigateToPage() function)
1. Filter in ABMSessionCreator is called
2. WebSocket_Connected is called, entering (*1*), saving a reference to all variables + the page
3. Page_Ready() is called, make sure in ConnectPage you initialize all your variables! (e.g. a List, or Map)
Event (*2*) happened (The websocket has been interrupted, e.g. due because the internet was temporary lost and has now reconnected)
1. WebSocket_Connected is called, entering (*2*), loading all the references to the variables + the page. Do not reinitialize your variables!
Private Sub WebSocket_Connected (WebSocket1 As WebSocket)
Log("Connected")
ws = WebSocket1
Dim session As HttpSession = ws.UpgradeRequest.GetSession ' NEW 2.01
If ABMShared.NeedsAuthorization Then
If session.GetAttribute2("IsAuthorized", "") = "" Then
ABMShared.NavigateToPage(ws, "../")
Return
End If
End If
If session.HasAttribute("ABMPage") = False Or session.HasAttribute("ABMNewSession") = True Then ' NEW 2.01 (*1*)
Log("saving session")
' IMPORTANT!
session.RemoveAttribute("ABMNewSession")
' IMPORTANT: Redim to reinit the page object
Dim page As ABMPage
' reload the BuildPage
BuildPage
' connect our page with the websocket
page.SetWebSocket(ws)
' Prepare the page
page.Prepare
' save at least page
session.SetAttribute("ABMPage", page) ' has to be done manually, SaveSessionVariables can't handle a page object.
' And all other variables you need for your program
page.SaveSessionVariables(Me, session)
Else ' (*2*)
' restore the page
Log("Loading session")
' load at least the page
page = session.GetAttribute("ABMPage")
' and load all your own variables previously saved
page.RestoreSessionVariables(Me, session)
' connect our page with the websocket
page.SetWebSocket(ws)
' refresh the page
page.Refresh
' because we use ShowLoaderType=ABM.LOADER_TYPE_MANUAL
page.FinishedLoading
End If
End Sub
b. In Websocket_disconnect() do the following:
Private Sub WebSocket_Disconnected
Log("Disconnected")
page.ws = Null
' And all other variables you need for your program
page.SaveSessionVariables(Me, ws.session)
End Sub
c. The new Page_ParseEvent (same as in ABMApplication)
Sub Page_ParseEvent(Params As Map)
Dim eventName As String = Params.Get("eventname")
Dim eventParams() As String = Regex.Split(",",Params.Get("eventparams"))
If eventName = "beforeunload" Then
Log("preparing for url refresh")
ws.session.SetAttribute("ABMNewSession", True)
Return
End If
If SubExists(Me, eventName) Then
Params.Remove("eventname")
Params.Remove("eventparams")
Select Case Params.Size
Case 0
CallSub(Me, eventName)
Case 1
CallSub2(Me, eventName, Params.Get(eventParams(0)))
Case 2
If Params.get(eventParams(0)) = "abmistable" Then
Dim PassedTables As List = ABM.ProcessTablesFromTargetName(Params.get(eventParams(1)))
CallSub2(Me, eventName, PassedTables)
Else
CallSub3(Me, eventName, Params.Get(eventParams(0)), Params.Get(eventParams(1)))
End If
Case Else
' cannot be called diretly, to many param
CallSub2(Me, eventName, Params)
End Select
End If
End Sub