B4J Question [BANanoServer] [SOLVED] Request assistance with jRDC2 error with ResumableSub

Mashiane

Expert
Licensed User
Ola

Download

I'm attempting to implement jRDC2 with my test project with the BANanoServer. I am able to perform CREATE, UPDATE, DELETE calls, however each of them results in an error.

1612115043597.png


Line 41203 has this kind of code.


B4X:
// [26] Public Sub Initialize
_B.initialize=function() {
// [29]  If ws.IsSupported Then
if (!(typeof WebSocket === 'undefined')) {

// [31]  ws.Initialize( {1} & BANano.Location.GetHost & {2} & BANano.StaticFolder & {3} )
_B._ws=MakeSocket("ws://"+window.location.host+"/ws/"+"www"+"/index", true);
if (typeof _B.websocket_disconnected==="function") {_B._ws.onclose = function(e) {_B.websocket_disconnected(e);
}};
if (typeof _B.websocket_onerror==="function") {_B._ws.onerror = function(e) {_B.websocket_onerror(e);}};
_B._ws.onmessage = function(e) {if(IsJson(e.data)){var ed=JSON.parse(e.data);
ed.hasOwnProperty("etype")?"runmethod"===ed.etype||"runmethodWithResult"===ed.etype||"setAutomaticEvents"===ed.etype||("runFunction"===ed.etype?b4j_runFunction(_B,ed.prop,ed.value):"runFunctionWithResult"===ed.etype?b4j_sendData(this,b4j_runFunction(_B,ed.prop,ed.value)):"eval"===ed.etype?b4j_eval(ed.value,ed.prop):"evalWithResult"===ed.etype?b4j_sendData(this,b4j_eval(ed.value,ed.prop)):"alert"===ed.etype?window.alert(ed.prop):_B.websocket_onmessage(e)):_B.websocket_onmessage(e)}else _B.websocket_onmessage(e)};
if (typeof _B.websocket_onopen==="function") {_B._ws.onopen = function(e) {_B.websocket_onopen(e);}}
if (typeof _B.websocket_onconnecting==="function") {_B._ws.onconnecting = function(e) {_B.websocket_onconnecting(e);}};
// [32]  End If
}
// End Sub
};


I am calling this BROWSERIndex call

B4X:
'process records to the MySQL Database, receive from router
Sub JRDC2OnBrowser(payload As Map)            'ignoreDeadCode
    Log("BrowserIndex.JRDC2OnBrowser")
    'convert the payload to json
    Dim jsonPayload As String = BANano.ToJson(payload)
    Log(jsonPayload)
    'push the payload to the server
    Dim resp As Object
    Dim prom As BANanoPromise = ws.RunFunctionWithResult("JRDC2OnServer", Array(jsonPayload))
    prom.Then(resp)
        Log(resp)

    prom.end
End Sub

Well I'm not sure if its the right way to do it because an jRDC2 call is a ResumableSub. JRDC2OnBrowser calls the JRDC2OnServer call. Whilst the sql commands are executed on the underlying db, the above error is always a result. Perhaps Im doing something wrong and would appreciate any assistance I can get.

B4X:
Sub JRDC2OnServer(payload As String) As ResumableSub
    Log("ServerIndex.JRDC2OnServer...")
    odbc.Initialize(payload)
    odbc.OpenJRDC2
    wait for (odbc.ToJRDC2) Complete (Done As Boolean)
    Return odbc.payload
End Sub

I have attached the source code and the SQL file for the backend database. There is a jRDC b4j project and some external libraries on the repo link above.

I thank you.

PS: the config.properties files on both projects hold the settings for the projects, the UI is on 55056 and the JRDC2 on 17178 (ports)
 
Last edited:

alwaysbusy

Expert
Licensed User
There are a couple of things wrong here:

1. global, you are reading the Browsers Log wrong. The error is "there is an unexpected ':' at VM126:3", not deeper into the stack as you are looking. There is nothing wrong with line 41203. It is as using a B4J callsub and getting an error in your own called method, but saying it is callsub that is wrong.

2. So if we look at the real error, it clearly marks there is something wrong with the data parameter in the json: an unknown object for JavaScript, ...ResumableSub... This means you've returned a unknown ResumableSub data type to Javascript.

3. So your assumtion is that a Promise in JavaScript can handle a B4J Resumable Sub, which it can't. Only B4J code can handle that (not even 'normal java') as it is a typical B4J statement. Agraham has written a nice technical document on how they work here: https://www.b4x.com/android/forum/threads/b4x-how-resumable-subs-work.102053/#content

The solution would be doing a call from B4J to the Browser when the B4J Wait For has been solved (there is something wrong with your odbc object code that overwrites the payload I suspect, see further, but that is something you have to solve yourself):

SERVERindex:
B4X:
Sub JRDC2OnServer(RequestID As String, payload As String) As ResumableSub
    Log("ServerIndex.JRDC2OnServer...")
    odbc.Initialize(payload)
    odbc.OpenJRDC2
    wait for (odbc.ToJRDC2) Complete (Done As Boolean)
    ' give the result to the browser
    ws.RunFunction("JRDC2OnServerBack", Array(RequestID, odbc.payload))
    ws.Flush
End Sub

BROWSERIndex:
B4X:
'process records to the MySQL Database, receive from router
Sub JRDC2OnBrowser(payload As Map)            'ignoreDeadCode
    Log("BrowserIndex.JRDC2OnBrowser")
    'convert the payload to json
    Dim jsonPayload As String = BANano.ToJson(payload)
    'push the payload to the server
  
    ' generate a unique ID so we know if JRDC2OnServerBack is called from the Server which result belongs to which call
    Dim requestID As String = BANano.GenerateUUID
    Log("Sending")
    Log(requestID)
    Log(jsonPayload)
   ' make the call to the server
    ws.RunFunction("JRDC2OnServer", Array(requestID, jsonPayload))  
End Sub

' the call the SERVER has to make with the result
Sub JRDC2OnServerBack(RequestID As String, payload As String)
    Log("Returns")
    Log(RequestID)
    Log(payload)
End Sub

Result when pressing Get AGE >= 30 AND Get ID = 1 immediately after and before the response from the first call is returned:

1612343319392.png


Looking a the UUIDs, the responses are returned in the correct order, however somewhere in your code the payload of call 1 has been overwritten by the one in call 2 in the B4J Server code in the odbc object. I don't see a new instance being created with each call.

Alwaysbusy
 
Last edited:
Upvote 0
Top