B4J Question [ABMaterial] Mobile browser problem

MichalK73

Active Member
Licensed User
Hello.

I have the following problem with ABMaterial. Namely, on some mobile browsers when I give the back on the phone and should return to the previous, it returns but the websocket is disconnected. The application works correctly on desktop browser. On mobile Opera, Chrome, Brave, Duckduck works correctly, when I press back it returns to the previous page, loads from the cache if necessary and keeps the connection. However, on iOS Safari and Huawei the browser does not work. It disconnects the websocket and you have to refresh the page.
Chrome installed on Huawei works fine and the browser for Huawei does not work. However, users often use the factory browsers and do not install others.
Does anyone know how to deal with this?
 

alwaysbusy

Expert
Licensed User
Longtime User
Does anyone know how to deal with this?
We are quite firm with this: the software is tested on such and such browser/devices. It 'may' work on other combinations but we do not guarantee it and we do not give support. The user is well warned and advised about this before they use/purchase it and although some are somewhat hesitant, they do make the change if needed.

Chrome is our advised browser. iOS Safari is one of those browsers we stopped supporting: over the many years we had nothing but trouble with it so we've given up. One version works, the next Safari version it breaks and then another Safari update it does work again. Especially WebSockets are badly implemented in Safari. I believe their latest bug has something to do with the TLS1.3/WebSockets combo. Those are the kind of bugs in the browsers we do have little to no control over ourselves. Factory browsers we have never supported, as they use outdated cores in many cases.

This approach works for us and our type of WebApps but it may not in you case.

If you have access to a Mac + an iOS device, I kind of remember you could remotely debug the iOS device on Macs Safari and see if it logs something from the device that may give you a clue why this happens.
 
Upvote 0

MichalK73

Active Member
Licensed User
The application is behind Cloudflare with TLS1.3. But yesterday I ran it over the network locally that is in debug mode.iPhone and Huawei were connecting to the ABMaterial server locally without SSL. However, I did not find anything special. It behaves as standard and the connection is broken.
I understand that you do not guarantee that it will work everywhere. I was just asking if anyone has a solution.
 
Upvote 0

alwaysbusy

Expert
Licensed User
Longtime User
I understand that you do not guarantee that it will work everywhere. I was just asking if anyone has a solution.
Sorry, I did mean this is how we communicate it towards our end users, not you, the programmer using ABM. I do try to support as many browser/devices combo as possible.

Wouldn't the above functions not just trigger even more disconnects?

How does your code look like in WebSocket_Connected? This is mine:
B4X:
Private Sub WebSocket_Connected (WebSocket1 As WebSocket)
    ws = WebSocket1
    
    Log(ABMShared.FormatDateTimeNow(Name) & "Connected")
    ABMPageId = ABM.GetPageID(page, Name,ws)
    Dim session As HttpSession = ABM.GetSession(ws, ABMShared.SessionMaxInactiveIntervalSeconds)
    If session.IsNew Then
        Log(ABMShared.FormatDateTimeNow(Name) & "Session is new")
        session.Invalidate
        ABMShared.NavigateToPage(ws, "", "./", False)
        Return
    End If
    
    If ABMShared.NeedsAuthorization Then
        If session.GetAttribute2("IsAuthorized2020", "") = "" Then
            Log(ABMShared.FormatDateTimeNow(Name) & "Not authorized")
            ABMShared.NavigateToPage(ws, ABMPageId, "../",False)
            Return
        End If
        Config = ABMShared.AllowedToNavigate(page, page.ws.UpgradeRequest.GetParameter("id"), Name)
        
        If Config.URL <> "" Then
            Log(ABMShared.FormatDateTimeNow(Name) & "Wrong page")
            ABMShared.NavigateToPage(ws, ABMPageId, Config.URL, False)
            Return
        End If
    End If
    
    ABM.UpdateFromCacheDebug(Me, ABMShared.CachedPages, ABMPageId, ws, ABMShared.UpdateCacheDebug)
    page.ws = ws
    BrowserTZ = ABM.Util.GetBrowserTimeZone(page)
    If page.ComesFromPageCache Then
        ' when we have a page that is cached it doesn't matter if it comes or not from a new connection we serve the cached version.
        Log(ABMShared.FormatDateTimeNow(Name) & "Comes from cache")
        page.Refresh
        page.FinishedLoading
    Else
        If page.WebsocketReconnected Then
            Log(ABMShared.FormatDateTimeNow(Name) & "Websocket reconnected")
            ' when we have a client that doesn't have the page in cache and it's websocket reconnected and also it's session is new - basically when the client had internet problems and it's session (and also cache) expired before he reconnected so the user has content in the browser but we don't have any on the server. So we need to reload the page.
            ' when a client that doesn't have the page in cache and it's websocket reconnected but it's session is not new - when the client had internet problems and when he reconnected it's session was valid but he had no cache for this page we need to reload the page as the user browser has content, reconnected but we have no content in cache
            Dim extra As String = ws.UpgradeRequest.FullRequestURI
            ABMShared.NavigateToPage (ws, ABMPageId, extra.Replace("/ws/", "/"),False)
        Else
            ' when the client did not reconnected it doesn't matter if the session was new or not because this is the websockets first connection so no dynamic content in the browser ... we are going to serve the dynamic content...
            Log(ABMShared.FormatDateTimeNow(Name) & "Websocket first connection")
            page.Prepare
            ConnectPage
        End If
    End If
    Log(ABMShared.FormatDateTimeNow(Name) & ABMPageId)
End Sub

And this is my ParseEvent (calls a method in a shared module):
B4X:
Sub Page_ParseEvent(Params As Map)
    ABMShared.ParseEvent(Me, page, ABMPageId, Params, Name)
End Sub

' in module ABMShared:
public Sub ParseEvent(self As Object, Page As ABMPage, ABMPageID As String, Params As Map, Name As String)
    Dim eventName As String = Params.Get("eventname")
    Dim eventParams() As String = Regex.Split(",",Params.Get("eventparams"))
    'Log(eventName)
    If eventName = "beforeunload" Then
        'Log(FormatDateTimeNow(Name) & "preparing for url refresh")
        ABM.RemoveMeFromCache(CachedPages, ABMPageID)
        Return
    End If
    Dim caller As Object = Page.GetEventHandler(self, eventName)    
    If caller = self Then
        If SubExists(self, eventName) Then
            Params.Remove("eventname")
            Params.Remove("eventparams")
            If eventName = "page_dropped" Then
                Page.ProcessDroppedEvent(Params)
            End If
            Select Case Params.Size
                Case 0
                    CallSub(self, eventName)
                Case 1
                    CallSub2(self, 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(self, eventName, PassedTables)
                    Else
                        CallSub3(self, eventName, Params.Get(eventParams(0)), Params.Get(eventParams(1)))
                    End If
                Case Else
                    ' cannot be called directly, to many param
                    CallSub2(self, eventName, Params)
            End Select
        End If
    Else
        CallSubDelayed2(caller, "ParseEvent", Params) 'ignore
    End If
End Sub

Also, the latest version of ABM has some extra Page events that may be of some help to locate the problem:
B4X:
Sub Page_Expired()
    Log(ABMShared.FormatDateTimeNow(Name) & ABMPageId & " was expired! Reloading")
    ABMShared.NavigateToPage(ws, "", "./", False)
End Sub

Sub Page_StillCached()
    Log(ABMShared.FormatDateTimeNow(Name) & ABMPageId & " was still valid after Scavenge")
End Sub

Alwaysbusy
 
Upvote 0

MichalK73

Active Member
Licensed User
Yes I know I'm using 4.95.
Do you have

ABMShared.NavigateToPage(ws, "", "./", False)

is the equivalent of

ABMShared.NavigateToPageNewTab(ws, "", "./", False)

in 4.51 ?


It doesn't.
Maybe it's some internal procedure of yours and may not be important to me.
 
Upvote 0
Top