B4J Question Example of Secure Websocket (wss://) Jserver+Client

Magma

Expert
Licensed User
Longtime User
Well I am searching the forum from morning....and can't find... need glasses...

and real i can't find any example of B4j Websocket Secure Server side <-> client b4j

and specifically with self created certificate... at any port...

searched: wss smiley, wss server, wss example, b4j websocket... and hundreds..
(i remembered say somewhere that wss smiley - but only some lines found)


For those moments need a chat... posting thread for finding threads / i am feeling bad for this... "sorry"
 

Magma

Expert
Licensed User
Longtime User
From server side as i know... will be like that:

B4X:
Sub AppStart (Args() As String)
    srvr.Initialize("")
    srvr.Port = settingsmap.Get(port)
   ConfigureSSL(portssl)
    srvr.AddWebSocket("/ws", "connectws")
...
srvr.Start

End sub

Private Sub ConfigureSSL (SslPort As Int)
    'example of SSL connector configuration
    Dim ssl As SslConfiguration
    ssl.Initialize
    ssl.SetKeyStorePath(File.DirApp, "xxxxxxx") 'path to keystore file
    ssl.KeyStorePassword = "xxxxxxxx"
    'ssl.KeyManagerPassword = "xxxxxxxx"
    srvr.SetSslConfiguration(ssl, SslPort)
    'add filter to redirect all traffic from http to https (optional)
    srvr.AddFilter("/*", "HttpsFilter", False)
End Sub

The class of connectws.... will be like that - or changing something because of wss-self created cert ? (need something)
'WebSocket class
Sub Class_Globals
    Private ws As WebSocket
End Sub

Public Sub Initialize
End Sub

Sub SetMaxTextMessage(size As Int)
    Dim jo As JavaObject = ws
    jo = jo.GetFieldJO("session").RunMethod("getPolicy", Null)
  ..
End Sub
Sub SetMaxBinaryMessage(size As Int)
    Dim jo As JavaObject = ws
    jo = jo.GetFieldJO("session").RunMethod("getPolicy", Null)
...
End Sub

Private Sub WebSocket_Connected (WebSocket1 As WebSocket)
    ws = WebSocket1
End Sub


Sub Device_Message(Params As Map)
...



From client... will be like this:

B4X:
    Public ws As WebSocketClient
    Private CallBack As Object
    Private EventName As String
....
..
    CallBack = vCallback
    EventName = vEventName
    ws.Initialize("ws")
    'accept all trust manager
    Dim ssl As JavaObject
    ssl.InitializeNewInstance("org.eclipse.jetty.util.ssl.SslContextFactory", Array(True))
    Dim jo As JavaObject = ws
    Dim wsc As JavaObject
    wsc.InitializeNewInstance("org.eclipse.jetty.websocket.client.WebSocketClient", Array(ssl))
    jo.SetField("wsc", wsc)
    SetMaxSizeText
    SetMaxSizeBinary
End Sub


...something wrong here... i think... i can't understand if at server side or client... an wss example will help...

well it is first time using websocket with ssl... okhttputils2/httpjob working "flawless" and already using it in many projects with ssl -> but websocket seems to need more config...
 
Last edited:
Upvote 0

Magma

Expert
Licensed User
Longtime User
I was hoping making mistake at code... check my code line by line... have a lot of LOG.. for debugging... but...

but no... all it's ok.... (until someone find the mistake)... well jserver response ok when calling with httpjob (from a client app) with HU2_ACCEPTALL at browser or client app receive the result...

but at websocket - connecting and never send data to server or after (full buffer?) having this error:
(EOFException) java.io.EOFException: HttpConnectionOverHTTP@6acb5773(l:/192.168.168.4:52993 <-> r:/192.168.168.3:17178,closed=false)=>HttpChannelOverHTTP@4d6aeae5(exchange=HttpExchange@43ad0d38 req=TERMINATED/null@null res=PENDING/null@null)[send=HttpSenderOverHTTP@47928195(req=QUEUED,snd=COMPLETED,failure=null)[HttpGenerator@2900703{s=START}],recv=HttpReceiverOverHTTP@1837f876(rsp=IDLE,failure=null)[HttpParser{s=CLOSED,0 of -1}]]<-DecryptedEndPoint@33d8e285{/192.168.168.3:17178<->/192.168.168.4:52993,OPEN,fill=-,flush=-,to=1/0}->HttpConnectionOverHTTP@6acb5773(l:/192.168.168.4:52993 <-> r:/192.168.168.3:17178,closed=false)=>HttpChannelOverHTTP@4d6aeae5(exchange=HttpExchange@43ad0d38 req=TERMINATED/null@null res=PENDING/null@null)[send=HttpSenderOverHTTP@47928195(req=QUEUED,snd=COMPLETED,failure=null)[HttpGenerator@2900703{s=START}],recv=HttpReceiverOverHTTP@1837f876(rsp=IDLE,failure=null)[HttpParser{s=CLOSED,0 of -1}]]->SocketChannelEndPoint@60954342{/192.168.168.3:17178<->/192.168.168.4:52993,ISHUT,fill=-,flush=-,to=1/0}{io=0/0,kio=0,kro=1}->SslConnection@62bff84c{NEED_WRAP,eio=-1/-1,di=-1}=>HttpConnectionOverHTTP@6acb5773(l:/192.168.168.4:52993 <-> r:/192.168.168.3:17178,closed=false)=>HttpChannelOverHTTP@4d6aeae5(exchange=HttpExchange@43ad0d38 req=TERMINATED/null@null res=PENDING/null@null)[send=HttpSenderOverHTTP@47928195(req=QUEUED,snd=COMPLETED,failure=null)[HttpGenerator@2900703{s=START}],recv=HttpReceiverOverHTTP@1837f876(rsp=IDLE,failure=null)[HttpParser{s=CLOSED,0 of -1}]]

Have in mind... trying to send byte->string into a map (a large one)... that works perfect without SSL thing...

The code that send that map / do i need something to add at this code when ssl enabled:
B4X:
Public Sub Initialize (vCallback As Object, vEventName As String)
    CallBack = vCallback
    EventName = vEventName
    ws.Initialize("ws")
    'accept all trust manager
    If Main.willbehttp="https" Then  'at main have that to enable/disable ssl - for testing my app without ssl-working ok..
        Dim ssl As JavaObject
        ssl.InitializeNewInstance("org.eclipse.jetty.util.ssl.SslContextFactory", Array(True))
        Dim jo As JavaObject = ws
        Dim wsc As JavaObject
        wsc.InitializeNewInstance("org.eclipse.jetty.websocket.client.WebSocketClient", Array(ssl))
        jo.SetField("wsc", wsc)
    End If

    SetMaxSizeText
    SetMaxSizeBinary
End Sub

...

Public Sub SendEventToServer(Event As String, Data As Map)
    'Try
    Dim m As Map
    m.Initialize
    m.Put("type", "event")
    m.Put("event", Event)
    m.Put("params", Data)
    Dim jg As JSONGenerator
    jg.Initialize(m)
    ws.SendText(jg.ToString)
    'Catch
    'End Try
End Sub

Public Sub Connect(Url As String)
    ws.Connect(Url)
End Sub

Public Sub Close
    If ws.Connected Then ws.Close
End Sub

...
 
Upvote 0

Magma

Expert
Licensed User
Longtime User
Yes I found the ERROR !!!!!

but i ll need help as i said i have no mistake/syntax error at code...

The problem is the "big string" (is the bytes->string)- but why is working good with no ssl and not with ssl :-(

"if i REM the string or set it null (it is acutally a photo turned to bytes and then string ~3MB) - works" // with no ssl working perfect...

any fix for that... ?? what can i do ?

ps: @Erel ...is wss://192.168.168.3:17178/ws (if i set ssl port 17178)
 
Last edited:
Upvote 0

alwaysbusy

Expert
Licensed User
Longtime User
I don't know if it is the same in your case, but with web and I need to do an upload of a bigger file, I set this in my WebSocket_connected(Websocket1 as WebSocket):

B4X:
Dim jo As JavaObject = WebSocket1
jo = jo.GetFieldJO("session").RunMethod("getPolicy", Null)
jo.RunMethod("setMaxTextMessageSize", Array(1024*1024*5)) ' 5Mb

But I do the transfer of the file itself over a normal Handler.

Alwaysbusy
 
Last edited:
Upvote 0

Magma

Expert
Licensed User
Longtime User
Well i had already set bigger textmessagesize....
it had Array(4 * 1024 * 1024)... now i turn it at Array(6 * 1024 * 1024)...

as i understand the size of image is about 3MB without ssl works ok...
double-size the "buffer" helps... but slow and sometimes get errors...


B4X:
Sub SetMaxTextMessage(size As Int)
    Dim jo As JavaObject = ws
    jo = jo.GetFieldJO("session").RunMethod("getPolicy", Null)
    jo.RunMethod("setMaxTextMessageSize", Array(6 * 1024 * 1024)) '4mb
End Sub
Sub SetMaxBinaryMessage(size As Int)
    Dim jo As JavaObject = ws
    jo = jo.GetFieldJO("session").RunMethod("getPolicy", Null)
    jo.RunMethod("setMaxBinaryMessageSize",Array(6 * 1024 * 1024)) '4mb
End Sub

that seems working a little better but have some freezes at a pc with low mem specs (3.5GB RAM)...

if i change VirtualMachineArgs???... now i have these settings...
B4X:
    #VirtualMachineArgs: -Xms1024m -Xmx3072m

do i need something bigger... ? - at the release/standalone what i must change to use more RAM... ??

SSL
seems very heavy compared with no SSL Websocket ... it think i ve learned a lesson today... (i know that all data encrypted + playing with ports, but i didn't know the size of RAM needs to encrypt, and ofcourse the power of cpu needs)

I think the topic title must be changed... to SSL/Jserver WebSocket need more RAM, CPU ?
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
How are you encoding your pictures? Base64? Some other method? 3.5GB Ram should be plenty, unless you have a hundreds of image uploads at the same time.
 
Upvote 0

Magma

Expert
Licensed User
Longtime User
@OliverA ..Base64... :-( - is there a better way ? - tried to zlib the bytes before encode to Base64... but when encoding to Base64 the result is bigger...

actually:
---every picture is about 280KB (base64 .length) (can be 3x at same time)
---the same time uploading at the same websocket (at the map) about 80KB of simple text/string/int
---and someway it is something like streaming.. because at the end of picture trying to upload a new one... so actually is 3~4MB /sec (at ~100Mbps connection)

but SSL+websocket make it very heavy.... and i am thinking may be is the key... i used a very standard way to create the self signed certificate... if i lower the bits of security ?

---------------------------------------------------------------
...just a simple search on google (a random pick):
https://avinetworks.com/docs/18.2/ssl-performance/
Memory

Memory allocation for a Service Engine, which primarily impacts the number of concurrent connections, can be anywhere between 1 and 128 GB. See SE Memory Consumption for a verbose description of expected concurrent SSL connections. As a general rule of thumb, SSL connections consume about twice as much memory as HTTP layer 7 connections, and four times as much memory as layer 4 with TCP proxy.

another example - that makes me unhappy:
https://www.hivemq.com/blog/how-does-tls-affect-mqtt-performance/
Conclusion

TLS affects performance significantly, especially CPU usage during the handshake. Once MQTT clients are connected, the overhead is negligible. We used X509 server certificates with highest security standards (4096-bit certificates) which additionally affected performance in a negative way. Nevertheless, once MQTT clients are connected, there isn’t significant performance overhead for 50.000 MQTT clients that are handling 10.000 messages per second with QoS 1, disk persistence and 50.000 distinct topics.


Tips for further reducing TLS overhead:


  • Using a Load Balancer with SSL Termination. Many Load Balancers support SSL offloading which can increase performance significantly.
  • SSL Session Resumption with Session IDs can be used to avoid a complete TLS handshake when a MQTT client reconnects. Bear in mind that session resumption is most secure when using cipher suites that have Perfect Forward Secrecy characteristics.
  • X509 certificates with smaller key length (e.g. 1024-bit or 2048-bit) could be used.
  • Elliptic Curve Cryptography (ECC) could potentially reduce CPU consumption.
 
Last edited:
Upvote 0
Top