@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