B4A Library [Moved] Socket.IO Client Library

Are you using it in a service and have any error?
Note that the Serverpart can not be done in B4A. Only the Clientpart but this should work in a Service.
 
I'm using it in an app. But if I Dim SocketIOClient in Process Globals it gives an error "Cannot access activity object from sub Process_Globals". If I do it inside service_Create it fails at runtime.
 
java.lang.NullPointerException
at com.brandsum.socketio.SocketIO$10.call(SocketIO.java:84)
at io.socket.emitter.Emitter.emit(Emitter.java:117)
at io.socket.client.Socket.access$601(Socket.java:24)
at io.socket.client.Socket$5.run(Socket.java:186)
at io.socket.thread.EventThread.exec(EventThread.java:55)
at io.socket.client.Socket.emit(Socket.java:182)
at io.socket.client.Socket$3.run(Socket.java:144)
at io.socket.thread.EventThread$2.run(EventThread.java:80)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
at java.lang.Thread.run(Thread.java:838)
 
java.lang.NullPointerException
at com.brandsum.socketio.SocketIO$10.call(SocketIO.java:84)
at io.socket.emitter.Emitter.emit(Emitter.java:117)
at io.socket.client.Socket.access$601(Socket.java:24)
at io.socket.client.Socket$5.run(Socket.java:186)
at io.socket.thread.EventThread.exec(EventThread.java:55)
at io.socket.client.Socket.emit(Socket.java:182)
at io.socket.client.Socket$3.run(Socket.java:144)
at io.socket.thread.EventThread$2.run(EventThread.java:80)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
at java.lang.Thread.run(Thread.java:838)
Can you post full error log and your code in using [ code ] tag?
Are you getting this error while sending (emitting) something?
 
Code: Copy
#Region  Service Attributes 
    #StartAtBoot: False
   
#End Region

Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.
    Dim dit As PhoneEvents
End Sub

Sub Service_Create
    dit.Initialize("PhoneEvents")
    Dim socket As SocketIOClient
    socket.connect("http://172.16.1.72:3000/")
    socket.emit("battery_update","30",False)

   
End Sub

Sub Service_Start (StartingIntent As Intent)
'    Dim socket1 As SocketIOClient
End Sub

Sub Service_Destroy

End Sub

Sub PhoneEvents_BatteryChanged(Level As Int, Scale As Int, Plugged As Boolean, Intent As Intent)
   
    Log("BatteryChanged: Level = " & Level & ", Scale = " & Scale & ", Plugged = " & Plugged)
    Dim StrLevel = " " & Level
    Main.BatteryLevel = Level
End Sub

Sub PhoneEvents_ConnectivityChanged (NetworkType As String, State As String, Intent As Intent)
    Log("ConnectivityChanged: " & NetworkType & ", state = " & State)
    Log(Intent.ExtrasToString)
End Sub
Code: Copy
** Activity (main) Create, isFirst = true **
Event iam data 16118
** Activity (main) Resume **
** Service (oplaaidat) Create **
** Service (oplaaidat) Start **
ConnectivityChanged: WIFI, state = CONNECTED
BatteryChanged: Level = 48, Scale = 100, Plugged = true
** Service (httputils2service) Create **
** Service (httputils2service) Start **
** Service (httputils2service) Start **
** Service (httputils2service) Start **
BatteryChanged: Level = 48, Scale = 100, Plugged = true
java.lang.NullPointerException
    at com.brandsum.socketio.SocketIO$10.call(SocketIO.java:84)
    at io.socket.emitter.Emitter.emit(Emitter.java:117)
    at io.socket.client.Socket.access$601(Socket.java:24)
    at io.socket.client.Socket$5.run(Socket.java:186)
    at io.socket.thread.EventThread.exec(EventThread.java:55)
    at io.socket.client.Socket.emit(Socket.java:182)
    at io.socket.client.Socket$3.run(Socket.java:144)
    at io.socket.thread.EventThread$2.run(EventThread.java:80)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
    at java.lang.Thread.run(Thread.java:838)
** Activity (main) Pause, UserClosed = true **
Connection established
java.lang.NullPointerException
    at com.brandsum.socketio.SocketIO$9.call(SocketIO.java:90)
    at io.socket.emitter.Emitter.emit(Emitter.java:117)
    at io.socket.client.Socket.access$601(Socket.java:24)
    at io.socket.client.Socket$5.run(Socket.java:186)
    at io.socket.thread.EventThread.exec(EventThread.java:55)
    at io.socket.client.Socket.emit(Socket.java:182)
    at io.socket.client.Socket.onconnect(Socket.java:389)
    at io.socket.client.Socket.onpacket(Socket.java:283)
    at io.socket.client.Socket.access$100(Socket.java:24)
    at io.socket.client.Socket$2$2.call(Socket.java:120)
    at io.socket.emitter.Emitter.emit(Emitter.java:117)
    at io.socket.client.Manager.ondecoded(Manager.java:427)
    at io.socket.client.Manager.access$1600(Manager.java:30)
    at io.socket.client.Manager$7.call(Manager.java:403)
    at io.socket.parser.IOParser$Decoder.add(IOParser.java:105)
    at io.socket.client.Manager.ondata(Manager.java:419)
    at io.socket.client.Manager.access$1000(Manager.java:30)
    at io.socket.client.Manager$2.call(Manager.java:370)
    at io.socket.emitter.Emitter.emit(Emitter.java:117)
    at io.socket.engineio.client.Socket.onPacket(Socket.java:551)
    at io.socket.engineio.client.Socket.access$1000(Socket.java:36)
    at io.socket.engineio.client.Socket$5.call(Socket.java:335)
    at io.socket.emitter.Emitter.emit(Emitter.java:117)
    at io.socket.engineio.client.Transport.onPacket(Transport.java:126)
    at io.socket.engineio.client.transports.Polling.access$700(Polling.java:18)
    at io.socket.engineio.client.transports.Polling$2.call(Polling.java:127)
    at io.socket.engineio.parser.Parser.decodePayload(Parser.java:241)
    at io.socket.engineio.client.transports.Polling._onData(Polling.java:135)
    at io.socket.engineio.client.transports.Polling.onData(Polling.java:102)
    at io.socket.engineio.client.transports.PollingXHR$5$1.run(PollingXHR.java:125)
    at io.socket.thread.EventThread$2.run(EventThread.java:80)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
    at java.lang.Thread.run(Thread.java:838)
 
Code: Copy
Sub Service_Create
    dit.Initialize("PhoneEvents")
    Dim socket As SocketIOClient
    socket.initialize("eventName") '<- Initialize before connecting
    socket.connect("http://172.16.1.72:3000/")
    'socket.emit("battery_update","30",False) '<-- you should call this after connection established
End Sub

You should initialize first and wait for the connection. After successful connection emit whatever you want. If you want to use it in service SocketIOClient should be declared in Process_Global. I know this is an Activity Object so you can't do this at this moment.

if I Dim SocketIOClient in Process Globals it gives an error "Cannot access activity object from sub Process_Globals".

I'll work on this issue tonight.
 
I'm using it in an app. But if I Dim SocketIOClient in Process Globals it gives an error "Cannot access activity object from sub Process_Globals". If I do it inside service_Create it fails at runtime.
Hi @QuentinB3 , That problem has been fixed. Now you can declare SocketIO in process_globals. I've uploaded v2. Please download and replace with previous one.
 
Any help with this conflict?

Code: Copy
Uncaught translation error: java.lang.IllegalArgumentException: already added: Lokhttp3/Cache$CacheRequestImpl$1;
Uncaught translation error: java.lang.IllegalArgumentException: already added: Lokhttp3/Cache$CacheResponseBody;
UNEXPECTED TOP-LEVEL EXCEPTION:
java.lang.RuntimeException: Translation has been interrupted
    at com.android.dx.command.dexer.Main.processAllFiles(Main.java:692)
    at com.android.dx.command.dexer.Main.runMonoDex(Main.java:315)
    at com.android.dx.command.dexer.Main.runDx(Main.java:293)
    at com.android.dx.command.dexer.Main.main(Main.java:249)
    at com.android.dx.command.Main.main(Main.java:94)
Caused by: java.lang.InterruptedException: Too many errors
    at com.android.dx.command.dexer.Main.processAllFiles(Main.java:684)
    ... 4 more
Picked up _JAVA_OPTIONS: -Djava.net.preferIPv4Stack=true

Using:
upload_2019-2-22_19-8-39.png


Thanks!
FBP
 
Solved... by removing dependencies on SocketIOClient.xml

Code: Copy
    <dependsOn>okhttp-3.8.1</dependsOn>
    <dependsOn>okio-1.13.0</dependsOn>
 
Any help with this conflict?

Code: Copy
Uncaught translation error: java.lang.IllegalArgumentException: already added: Lokhttp3/Cache$CacheRequestImpl$1;
Uncaught translation error: java.lang.IllegalArgumentException: already added: Lokhttp3/Cache$CacheResponseBody;
UNEXPECTED TOP-LEVEL EXCEPTION:
java.lang.RuntimeException: Translation has been interrupted
    at com.android.dx.command.dexer.Main.processAllFiles(Main.java:692)
    at com.android.dx.command.dexer.Main.runMonoDex(Main.java:315)
    at com.android.dx.command.dexer.Main.runDx(Main.java:293)
    at com.android.dx.command.dexer.Main.main(Main.java:249)
    at com.android.dx.command.Main.main(Main.java:94)
Caused by: java.lang.InterruptedException: Too many errors
    at com.android.dx.command.dexer.Main.processAllFiles(Main.java:684)
    ... 4 more
Picked up _JAVA_OPTIONS: -Djava.net.preferIPv4Stack=true

Using:
View attachment 77646

Thanks!
FBP
Hi, @fbritop now you can use SocketIOClient with OkHttpUtils2. That conflict issue has been resolved. You need to remove all previous jar files and extract the attached zipped jar files.
 
Last edited:
Is it possible to reply to an incoming message directly over the message?. I have done it with nodejs socketio Client in linux. So when I receive a command, it issues a callback over the same message:

A node JS gets a rest request, so it emits a message to a device, and wait for the callback from the device before sending the reply back to the REST request

Server:
Code: Copy
devices[queryData.idDevice].emit('open', data, function (retorno) {
   var now2 = new Date();
   var now3 = (now2-now)/1000
   var now4=Math.round(now3*10)/10
   logg(logDate() + "CMD ACK IN " + now4 + "s! (" + now3 + ")")
   logg(logDate() + retorno);
   res.end(retorno);
   return;
})


Client:
Code: Copy
socket.on('open', function(data, fn){
    log(chalk.green.bold("Open CMD RX"));
    fn('{"code":"answer","resultCode":0,"result":"ACK"}');
})

Not sure if it can be done with this library.
Thanks in advance
 
Is it possible to reply to an incoming message directly over the message?. I have done it with nodejs socketio Client in linux. So when I receive a command, it issues a callback over the same message:

A node JS gets a rest request, so it emits a message to a device, and wait for the callback from the device before sending the reply back to the REST request

Server:
Code: Copy
devices[queryData.idDevice].emit('open', data, function (retorno) {
   var now2 = new Date();
   var now3 = (now2-now)/1000
   var now4=Math.round(now3*10)/10
   logg(logDate() + "CMD ACK IN " + now4 + "s! (" + now3 + ")")
   logg(logDate() + retorno);
   res.end(retorno);
   return;
})


Client:
Code: Copy
socket.on('open', function(data, fn){
    log(chalk.green.bold("Open CMD RX"));
    fn('{"code":"answer","resultCode":0,"result":"ACK"}');
})

Not sure if it can be done with this library.
Thanks in advance
That is not possible yet. Currently emit method will raise an acknowledgment event. Sending acknowledgment on message received will be added in next update. May be today or tomorrow.
 
Thanks @Brandsum. One thing I noticed, if i do the server emit with callback, then the event signature changes (it throw me an error at first), so I added a second object to the sub signature on B4A and it pass. When I checked the getType of the second signature object, it was a socketIOClient type, but the only method I could execute with no error on that socket was the disconnect method. So under that situation, I can see that the original library is receiveing the callback object.

Thanks for the update in advance.
FBP
 
Back
Top