Android Tutorial Custom WebSocket Based Push Framework

marcick

Well-Known Member
Licensed User
Longtime User
Luca vai sicuro, che con un poll ogni 30sec. (keep-alive) il tuo server dopo i primi 10K clienti scoppia... Io l'ho installato su un server cloud di Aruba e va molto bene, ma ogni cliente chiede un socket e i socket sono limitati....
Ciao
Mauro

Hi Mauro, where is exactely the limit ? I have rent a cloud server on Aruba running windows and I manage to write a VB.NET app that receive incoming TCP (or UDP, still have to understand what's better) connection from hundreds of devices (potentially thousands) and store data in a database. It will be a server based fleet tracking application. What do you exactely mean with "socket are limited" ?
Marco
 

tigrot

Well-Known Member
Licensed User
Longtime User
Depending on windows' version there are "commercial" limits in the number of opened connections. Aruba(my preferred provider) has limit only in memory usage. Use TCP, it's safer than UDP. Ask Aruba for the windows version which is better for your deployment.
Ciao
Mauro
 

marcick

Well-Known Member
Licensed User
Longtime User
Hi Mauro, thanks.
Meanwhile I made some progresses. My Aruba cloud server is Windows 2008 64 bit WAMP (just picked from the template list without knowing nothing about the better version). Everything is working fine in TCP now, but still have to discover what happens when there will be hundreds of requests in the same time ....
Ciao
Marco
 

vfafou

Well-Known Member
Licensed User
Longtime User
Hello!
Sometimes after a few hours working, I take the following errors:
B4X:
java.lang.RuntimeException: org.eclipse.jetty.websocket.api.WebSocketException: RemoteEndpoint unavailable, current state [CLOSED], expecting [OPEN or CONNECTED]
    at anywheresoftware.b4a.keywords.Common.CallSub4(Common.java:455)
    at anywheresoftware.b4a.keywords.Common.access$0(Common.java:426)
    at anywheresoftware.b4a.keywords.Common$CallSubDelayedHelper.run(Common.java:500)
    at anywheresoftware.b4a.keywords.SimpleMessageLoop.runMessageLoop(SimpleMessageLoop.java:30)
    at anywheresoftware.b4a.StandardBA.startMessageLoop(StandardBA.java:26)
    at anywheresoftware.b4j.object.WebSocketModule$Adapter$ThreadHandler.run(WebSocketModule.java:195)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
    at java.util.concurrent.FutureTask.run(FutureTask.java:262)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)
Caused by: org.eclipse.jetty.websocket.api.WebSocketException: RemoteEndpoint unavailable, current state [CLOSED], expecting [OPEN or CONNECTED]
    at org.eclipse.jetty.websocket.common.WebSocketSession.getRemote(WebSocketSession.java:245)
    at anywheresoftware.b4j.object.WebSocket.Flush(WebSocket.java:101)
    at rm.rmtunnel.pushb4a._sendmessages(pushb4a.java:1049)
    at rm.rmtunnel.pushb4a.callSub(pushb4a.java:1184)
    at anywheresoftware.b4a.keywords.Common.CallSub4(Common.java:430)
    ... 10 more


java.lang.RuntimeException: org.eclipse.jetty.websocket.api.WebSocketException: RemoteEndpoint unavailable, current state [CLOSED], expecting [OPEN or CONNECTED]
    at anywheresoftware.b4j.object.WebSocket.setEvents(WebSocket.java:378)
    at anywheresoftware.b4j.object.WebSocketModule$Adapter$ThreadHandler.run(WebSocketModule.java:190)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
    at java.util.concurrent.FutureTask.run(FutureTask.java:262)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)
Caused by: org.eclipse.jetty.websocket.api.WebSocketException: RemoteEndpoint unavailable, current state [CLOSED], expecting [OPEN or CONNECTED]
    at org.eclipse.jetty.websocket.common.WebSocketSession.getRemote(WebSocketSession.java:245)
    at anywheresoftware.b4j.object.WebSocket.sendText(WebSocket.java:107)
    at anywheresoftware.b4j.object.WebSocket.setEvents(WebSocket.java:375)
    ... 6 more


org.eclipse.jetty.websocket.api.WebSocketException: RemoteEndpoint unavailable, current state [CLOSED], expecting [OPEN or CONNECTED]
    at org.eclipse.jetty.websocket.common.WebSocketSession.getRemote(WebSocketSession.java:245)
    at anywheresoftware.b4j.object.WebSocket.Flush(WebSocket.java:101)
    at anywheresoftware.b4j.object.WebSocketModule$Adapter$1.run(WebSocketModule.java:131)
    at anywheresoftware.b4a.keywords.SimpleMessageLoop.runMessageLoop(SimpleMessageLoop.java:30)
    at anywheresoftware.b4a.StandardBA.startMessageLoop(StandardBA.java:26)
    at anywheresoftware.b4j.object.WebSocketModule$Adapter$ThreadHandler.run(WebSocketModule.java:195)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
    at java.util.concurrent.FutureTask.run(FutureTask.java:262)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)

After these errors, the connections or the application hangs!
Is it possible to be needed DebugNetworkLatency greater than 200?
 
Last edited:

vfafou

Well-Known Member
Licensed User
Longtime User
Hi Erel! Thank you for your reply!
After errors, it stops getting messages from tablets. It likes as closing the connections.
I have to tell you that I have implemented an AsyncStreams server into the same application in order to receive text messages from several VB6 clients of my LAN, and push them to tablets.
I haven't test it in debug mode with 200 devices needed. It's very difficult because of the infrastructure.
I'm sorry for any bother, but I'm very new to web applications and I'm trying very hard to create a system to talk an old VB6 app with tablets connected to Internet.
The websockets server is running under Linux Ubuntu with Java 1.7.75.
My machine is an HP Proliant 360 G6 with 4core XEON and 16GB RAM.
From time to time, I discover several settings that have to be done, like increasing the network connections of the OS, from 128 to 2048, start JAVA with Xms and Xmx modified e.t.c.
I don't know what else will be needed...
The errors happen when the number of connections is ~200.
I think that I haven't found all settings needed yet.
Any help is highly appreciated, because I have the system on production!
 

billzhan

Active Member
Licensed User
Longtime User
I found a websocket testing mod:
https://github.com/maciejzaleski/JMeter-WebSocketSampler

Jar files built can be found:
http://stackoverflow.com/questions/16152648/websocket-plugin-for-jmeter

I've tested websockets with Jmeter (not b4x clients).
Linode VPS(1G Ram/1 cpu) + ubuntu server/JRE1.7.65 server
To keep the connection, I ping (send dateticks ) every 30seconds, client ->server->client (heartbeat)
When concurrent connection number is 500~800, things are fine in 4 hours.
When concurrent connection number is 1000, JVM crashed after about 1 hour.

Lessons learned:
1. All the resources should be closed when ws disconnected.(sql/timer/ any variable called by other threads)
2. ws disconnections can be found, especially when the package loss>40%.
 

vfafou

Well-Known Member
Licensed User
Longtime User
Hello Erel!
Is this example multithreaded?
I mean does every PushB4A run on its own thread and the calls make run on is own thread?
I'm asking you because I see that you use CallSubDelayed.
 

vfafou

Well-Known Member
Licensed User
Longtime User
@billzhan,
Thank you for your reply!

You write:

Lessons learned:
2. ws disconnections can be found, especially when the package loss>40%.


My question is: how do you find the package loss percent in B4J?

Thank you in advance!
 

vfafou

Well-Known Member
Licensed User
Longtime User

AsyncStreams is used from socketserver in order to have managed client LAN connections into the same app that is running the websocket server, in order to push messages from my old VB6 app to the websocket server and vice versa (as real-time as allowed)!
May this is the problem.
Is there any other way to make this communication, with managed clients, into the same server application?
 
Last edited:

vfafou

Well-Known Member
Licensed User
Longtime User
Maybe create a small B4J program that will run together with the vb6 app on the client and will connect to the web socket server and the old client.
I was thinking of a little different solution: make a B4J separate SocketServer application, running on the server where is placed the web socket server and make one web socket connection. I think that your suggestion will be far better because the server will not take all this load.
Thank you!
 

vfafou

Well-Known Member
Licensed User
Longtime User
Hello!
The following code portions are contained into the server side of this tutorial, inside the class PushB4A.
Please tell me:
Below is a Server Event and we need to call ws.flush.
B4X:
Public Sub SendMessages(Messages As List)
    ws.RunFunction("NewMessage", Messages)
    ws.Flush
End Sub
Below is a Server Event and... why we don't need to call ws.flush?
B4X:
Public Sub Device_Ping(Data As Map)
    lastPingTime = DateTime.Now
    CallSubDelayed(PushShared, "UpdateBrowsers")
    ws.RunFunction("Pong", Null)
End Sub
Below is an Event that doesn't count as Server Event, so we don't need to call ws.flush!
B4X:
Public Sub Device_Id (Data As Map)
    id = Data.Get("id")
    Dim version As Double = Data.Get("version") 'ignore
    CallSubDelayed3(PushShared, "NewConnection", id, Me)
End Sub

Thank you in advance!
 
Cookies are required to use this site. You must accept them to continue using the site. Learn more…