B4J Question Websocket Server to server data to any websocket client(not b4x)

tufanv

Expert
Licensed User
Longtime User
Hello,

As discussed here: https://www.b4x.com/android/forum/threads/which-tutorial-to-follow-for-websockets.124814/ , I want to create a websocket for b4j to serve data via websocket to any websocket client(not only b4a). I followed the tutorial Erel posted on this previous topic linked above, but it was for b4x clients. I want to simply push json data to clients but with that tutorial it is only possible to send data like this which is for b4x clients:
{"prop":"ServerTime","etype":"runFunction","value":[51]}

What should I do to create a websocket for this ?

ty
 

cklester

Well-Known Member
Licensed User
I want to simply push json data to clients but with that tutorial it is only possible to send data like this which is for b4x clients:
{"prop":"ServerTime","etype":"runFunction","value":[51]}

That is JSON data, isn't it?
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
If you just want to send raw text, you can try this (note ws is set in WebSocket_Connected by the B4J template for a Server application):
B4X:
    Dim jo As JavaObject = ws
    jo = jo.GetFieldJO("session")
    Dim remoteJo As JavaObject = jo.RunMethodJO("getRemote", Null)
    remoteJo.RunMethod("sendString", Array("Some value", Null))
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
Forgot. If you are going to do it on your own, you also have to flush the output. Normally, you could use
B4X:
ws.Flush
but the B4J WebSocket code relies on a private variable in order to determine if a ws.Flush actually does a flush. So whenever you are ready to do a flush using the above method, you'll have to do a
B4X:
remoteJo.RunMethod("flush", Null)
 
Upvote 0

EnriqueGonzalez

Well-Known Member
Licensed User
Longtime User
Holy cow oliver took me a whole weekend to figure out what you just shared here. If only i had waited a little longer.
 
Upvote 0

tufanv

Expert
Licensed User
Longtime User
If you just want to send raw text, you can try this (note ws is set in WebSocket_Connected by the B4J template for a Server application):
B4X:
    Dim jo As JavaObject = ws
    jo = jo.GetFieldJO("session")
    Dim remoteJo As JavaObject = jo.RunMethodJO("getRemote", Null)
    remoteJo.RunMethod("sendString", Array("Some value", Null))
Works PERFECT ! Thanks very much
 
Upvote 0

tufanv

Expert
Licensed User
Longtime User
one more question about this,
I need to serve only the currencies user want so I need to implement a "subscribe" like method. After connection to websocket, user will subscribe to currencies they want, and only those currencies will be served to user. What method can be used for this ?

TY very much
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
You have to sent a JSON string to the server in the following format:
JSON:
{type: "event", event: xxxx, params: { p1name: p1value, p2name: p2value, ... } }
Where xxxx is the sub name that will be called on the B4J side. This sub name needs to include an underscore (_). So valid sub name:
subscribe_currency
Invalid subname:
suscribeCurrency
The params value is another JSON map that contains 0 or more key values itself. This map will be converted to a B4J map and will be passed on as the parameter for the sub that is called.

So sending
JSON:
{type: "event", event: "hello_world", params: {firstname: "John", lastname: "Doe"}}

And having the following code in the Server Socket Handler routine
B4X:
Public Sub hello_word(values As Map)
  Log($"Hello ${values.GetDefault("firstname", "Nothing")} ${values.GetDefault("lastname", "Nothing")}"$)
End Sub

Should log
Hello John Doe
on the server side.
Note: Code not tested. May contain show stopping typos.
 
Upvote 0

tufanv

Expert
Licensed User
Longtime User
You have to sent a JSON string to the server in the following format:
JSON:
{type: "event", event: xxxx, params: { p1name: p1value, p2name: p2value, ... } }
Where xxxx is the sub name that will be called on the B4J side. This sub name needs to include an underscore (_). So valid sub name:
subscribe_currency
Invalid subname:
suscribeCurrency
The params value is another JSON map that contains 0 or more key values itself. This map will be converted to a B4J map and will be passed on as the parameter for the sub that is called.

So sending
JSON:
{type: "event", event: "hello_world", params: {firstname: "John", lastname: "Doe"}}

And having the following code in the Server Socket Handler routine
B4X:
Public Sub hello_word(values As Map)
  Log($"Hello ${values.GetDefault("firstname", "Nothing")} ${values.GetDefault("lastname", "Nothing")}"$)
End Sub

Should log

on the server side.
Note: Code not tested. May contain show stopping typos.
Thank you so much !!
 
Upvote 0

tufanv

Expert
Licensed User
Longtime User
I have one more problem here.
When I send a textmessage from client to server, I always get this error on server side :

java.lang.NullPointerException
at anywheresoftware.b4j.object.WebSocketModule$Adapter.onWebSocketText(WebSocketModule.java:112)

On server side I have this code to catch sent messages:

B4X:
Private Sub ws_TextMessage(someText As String)
    Log(someText)
End Sub

What am i missing here ?
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
If this is the method is on the server side, the parameter must be a map. See my previous post
 
Upvote 0
Top