B4A Library Socket.IO Client Library

Hi everyone,

Here is the Socket.IO Client library wrap for this Github Project.
Click here for the B4i wrapper

SocketIOClient
Author:
@Biswajit
Version: 2.5
Dependency: OkHttpUtils2
  • SocketIOClient
    Method:
    • initialize(EventName As String)
    • connect (host As String, params As String, secure As Boolean)
    • connectWithOptions(host As String, params As String, secure As Boolean, reconnection As Boolean, reconnectionAttempts As Long, reconnectionDelay As Long, reconnectionDelayMax As Long, timeout As Long)
    • disconnect()
    • emit(event As String, data As Object)
    • addEvent(event As String, callback As String)
    • removeEvent(event As String, callback As String)
    • sendAck(ack As Object, data() As Object)
  • Events:
    • OnConnecting: will be raised at the first time it tries to connect to the server
    • OnConnectError(error As Object): will be raised if any error occurs when connecting
    • OnConnectionTimeout(timeout As Object): will be raised if the connection does not receive a response from the server after approximately 30 seconds
    • OnConnect: will be raised on successful connection
    • OnDisconnect(reason As Object): will be raised on connection disconnect. If the disconnection was initiated by the server, you need to reconnect manually else it will try itself to reconnect
    • OnReconnectAttempt(attemptNumber As Object): will be raised if it tries to reconnect after connection timeout or if connection disconnected from client side
    • OnReconnecting(attemptNumber As Object): will be raised on reconnection attempt
    • OnReconnect(attemptNumber As Object): will be raised on successful connection after connection timeout or if connection disconnected from client side
    • OnReconnectError(error As Object): will be raised if any error occurs when reconnecting
    • OnReconnectFailed: will be raised if when couldn’t reconnect within reconnectionAttempts
    • OnError(error As Object): will be raised if any error occurs

Example Attached.
For the server code you can check Socket.IO Github example or you can use this following chat server example (written in javascript) [attached]:

PHP:
var express = require('express');
var app = express();

// *** FOR HTTPS CONNECTION *** //
// const fs = require('fs');

// var options = {
//   key: fs.readFileSync('./key.pem'),
//   cert: fs.readFileSync('./cert.pem'),
//   passphrase: "password of cert/key file"
// };

// var server = require('https').createServer(options, app);
// *** FOR HTTPS CONNECTION *** //


// *** FOR HTTP CONNECTION *** //
var server = require('http').Server(app);
// *** FOR HTTP CONNECTION *** //

var io = require('socket.io')(server);
var users = {};


server.listen(999, function(){
  console.log('listening on *:999');
});

io.sockets.on('connection', function(socket){
    console.log("User Connected");

    socket.on('user_msg', function(data,callback){
        io.emit('new_message', data);
        callback("Data Received");
    });

    socket.on('disconnect', function(data){
        console.log('User disconnected');
    });
});

To run this example server code:
  1. Download NodeJS.
  2. Install it.
  3. Download library zip file and extract.
  4. Run cmd inside server folder
  5. Run npm install
  6. It will take some time to complete.
  7. After that run node app.js
  8. It will show listening on *:999
  9. Now create you app and connect.
  10. That's it!
  11. If you want to use HTTPS (secure connection) then for testing you can generate key and cert file using openssl
    Eg:
    openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365
Update v2:
  1. Now you can declare this in process_globals
  2. Some event signature has been modified (please check above)
  3. New event added OnError
Update v2.1:
  1. Conflict with B4A OkHttpUtils2 library (Fixed)
Update v2.2:
  1. Added support for a secure connection.
Update v2.3:
  1. Now you can detect data delivery via an acknowledgment of the emit event (Check Attached Example).
Update v2.4:
  1. Send acknowledgment with data to the server on receiving a message.
Update v2.5:
  1. Added query parameter support.
Update v2.6:
  1. Send any object instead of a string.
 

Attachments

  • Socket.IO-Simple-Example.zip
    9.8 KB · Views: 898
  • SocketIOClient_v2.6.zip
    159.2 KB · Views: 1,009
Last edited:

cheveguerra

Member
Licensed User
Longtime User
Is it happening on debug mode or release mode?
It is happening on release mode, if I comment the disabling and enabling of buttons everything works all right!!

If the server sends an ack object along with the message then you can use
Sub socket_notify(message As Object, ack As Object)

if the server sends only message then the signature will be
Sub socket_notify(message As Object)

Check your server code.

Thanks, that helped!!!

it works now!!

Edited code:
#Region  Project Attributes
    #ApplicationLabel: Socket.IO Simple Example
    #VersionCode: 1
    #VersionName:
    'SupportedOrientations possible values: unspecified, landscape or portrait.
    #SupportedOrientations: unspecified
    #CanInstallToExternalStorage: False
    #BridgeLogger : True
#End Region

#Region  Activity Attributes
    #FullScreen: False
    #IncludeTitle: True
#End Region

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

End Sub

Sub Globals
    'These global variables will be redeclared each time the activity is created.
    'These variables can only be accessed from this module.
    Dim socket As SocketIOClient
    Private StatusLbl As Label
    Private SendBtn As Button
    Private AckLbl As Label
    Private MsgInput As EditText
    Private ConnectBtn As Button
    Private DisconnectBtn As Button
End Sub

Sub Activity_Create(FirstTime As Boolean)
    'Do not forget to load the layout file created with the visual designer. For example:
    Activity.LoadLayout("Layout1")
End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)
    
End Sub

Sub ConnectBtn_Click
    socket.initialize("socket")
    socket.connect("http://11.0.0.139:999/","",False)
    'socket.connectWithOptions("https://192.168.0.103:999/","", True,True, 0,1000,5000,20000) 'connect with options
    StatusLbl.Text = "Connecting"
End Sub

Sub DisconnectBtn_Click
    socket.disconnect()
    StatusLbl.Text = "Disconnecting"
End Sub

Sub socket_OnConnect
    socket.addEvent("new_message","notify")
    StatusLbl.Text = "Connected"
'    DisconnectBtn.Enabled = True
'    Log("DisconnectBtn enable true")
'    SendBtn.Enabled = True
'    Log("SendBtn enable true")
'    MsgInput.Enabled = True
'    Log("MsgInput enable true")
'    ConnectBtn.Enabled = False
'    Log("ConnectBtn enable false")
End Sub

Sub socket_OnDisconnect(Reason As Object)
    socket.removeEvent("new_message","notify")
    StatusLbl.Text = "Disconnected"
'    ConnectBtn.Enabled = True
'    Log("ConnectBtn enable true")
'    SendBtn.Enabled = False
'    Log("SendBtn enable true")
'    MsgInput.Enabled = False
'    Log("SendBtn enable false")
'    DisconnectBtn.Enabled = False
'    Log("DisconnectBtn enable false")
End Sub

Sub socket_notify(message As Object) ', ack As Object
'    socket.sendAck(ack,Array("your data"))
    Log("socket_notify="&message)
End Sub

Sub SendBtn_Click
    socket.emit("user_msg", MsgInput.Text)
End Sub

' Recibimos el callback del servidor
Sub user_msg_ack(data As Object)
    AckLbl.Text = data
    Log("user_msg_ack="&data)
End Sub
 

feriot

Member
how can send json in 'emit'?
i used this codes but no success :

B4X:
Dim m As Map
m.Initialize
m.Put("id","Client_"&id)
m.Put("msg","Hi from client")
socket.emit("user_on",m)
 

feriot

Member
how can send json in 'emit'?
i used this codes but no success :

B4X:
Dim m As Map
m.Initialize
m.Put("id","Client_"&id)
m.Put("msg","Hi from client")
socket.emit("user_on",m)
it does not detect as a json obect in server side
 

Biswajit

Active Member
Licensed User
Longtime User
without any error. but does not connect.
i guess server side must use https. i'm trying to convert server codes to https edition
Check if you can browse the server ip from the device where you are running the app.

how can send json in 'emit'?
i used this codes but no success :

B4X:
Dim m As Map
m.Initialize
m.Put("id","Client_"&id)
m.Put("msg","Hi from client")
socket.emit("user_on",m)
If you want to use that JSON on the server side then send JSON string instead of a map.
 

DonManfred

Expert
Licensed User
Longtime User
it does not detect as a json obect in server side
Sure not. You are sending a MAP.
Use jsongenerator and generate a json for the Map.
 

jtim3032

Member
Licensed User
Longtime User
I have been using your excellent library for some time now. However, I am just in the process of making a new app available on the Play Store and there is a new requirement that the Target SDK must be at least 30. If I set the target SDK to anything higher than 27, the client fails to connect with the following:

Error Log:
Connecting...
IOSocket_OnConnectError: io.socket.engineio.client.EngineIOException: xhr poll error
io.socket.engineio.client.EngineIOException: xhr poll error
Tring to Reconnect
Reconnecting
IOSocket_OnConnectError: io.socket.engineio.client.EngineIOException: xhr poll error
io.socket.engineio.client.EngineIOException: xhr poll error
Reconnection Error
Tring to Reconnect
Reconnecting
IOSocket_OnConnectError: io.socket.engineio.client.EngineIOException: xhr poll error
io.socket.engineio.client.EngineIOException: xhr poll error
Reconnection Error
Tring to Reconnect
Reconnecting
IOSocket_OnConnectError: io.socket.engineio.client.EngineIOException: xhr poll error
io.socket.engineio.client.EngineIOException: xhr poll error
OnReconnectFailed:
Reconnection Failed
Reconnection Error

Am I missing a part of the SDK?
 

jtim3032

Member
Licensed User
Longtime User
UPDATE:

SDK 28 and beyond by default doesn't allow non-https communication. The following has to be added to the manifest:

B4X:
CreateResourceFromFile(Macro, Core.NetworkClearText)
 

Ibrahim Saleh

Member
Licensed User
Longtime User
B4X:
*** Service (starter) Create ***
** Service (starter) Start **
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
*** Service (socketclient) Create ***
** Service (socketclient) Start **
Connecting...
OnError
{"message":"Invalid namespace"}
An error occurs

I'm getting such an error when connecting to my server which a tested using web socker.io Js client-side and is working well. I have tried the above response but to no fix. I really need a solution.
 

Biswajit

Active Member
Licensed User
Longtime User
B4X:
*** Service (starter) Create ***
** Service (starter) Start **
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
*** Service (socketclient) Create ***
** Service (socketclient) Start **
Connecting...
OnError
{"message":"Invalid namespace"}
An error occurs

I'm getting such an error when connecting to my server which a tested using web socker.io Js client-side and is working well. I have tried the above response but to no fix. I really need a solution.
You have to pass the namespace after the hostname while connecting,

B4X:
socketio.connect("<your domain / ip>:port/<namespace>", "", true/fasle)
 

feriot

Member
HTTPS connection does not work on android 10 and above with B4A v11.5. but it's ok with B4A v11.2.
app exits when connecting event fires.
 

Biswajit

Active Member
Licensed User
Longtime User
HTTPS connection does not work on android 10 and above with B4A v11.5. but it's ok with B4A v11.2.
app exits when connecting event fires.
Please check the log if its throwing any errors or not.
 

alimanam3386

Active Member
Licensed User
Longtime User
Hi, I think you need to update the lib because it can not connect to server I get this error every time, with latest version of native library on server side ( version 4.5.2 )

on server anything is ok and server run correctly , but in client side ( b4a ) I get bellow error when I try to connect.

io.socket.engineio.client.EngineIOException: xhr poll error
 

jtim3032

Member
Licensed User
Longtime User
@Biswajit I recently updated B4A from 11.00 to 11.80 (64bit). Since then, the library throws the following error after any connection attempt. Target platform is 30. Reverting to version 11.00 and the problem goes away.

Hope you can help :)

Connecting...
java.lang.IllegalStateException: Unable to extract the trust manager on Android10Platform, sslSocketFactory is class com.android.org.conscrypt.OpenSSLSocketFactoryImpl
at okhttp3.OkHttpClient$Builder.sslSocketFactory(OkHttpClient.kt:751)
at io.socket.engineio.client.transports.WebSocket.doOpen(WebSocket.java:50)
at io.socket.engineio.client.Transport$1.run(Transport.java:82)
at io.socket.thread.EventThread.exec(EventThread.java:55)
at io.socket.engineio.client.Transport.open(Transport.java:77)
at io.socket.engineio.client.Socket.probe(Socket.java:472)
at io.socket.engineio.client.Socket.onOpen(Socket.java:485)
at io.socket.engineio.client.Socket.onHandshake(Socket.java:526)
at io.socket.engineio.client.Socket.onPacket(Socket.java:499)
at io.socket.engineio.client.Socket.access$1000(Socket.java:31)
at io.socket.engineio.client.Socket$5.call(Socket.java:313)
at io.socket.emitter.Emitter.emit(Emitter.java:117)
at io.socket.engineio.client.Transport.onPacket(Transport.java:134)
at io.socket.engineio.client.transports.Polling.access$700(Polling.java:17)
at io.socket.engineio.client.transports.Polling$2.call(Polling.java:124)
at io.socket.engineio.parser.Parser.decodePayload(Parser.java:188)
at io.socket.engineio.client.transports.Polling._onData(Polling.java:132)
at io.socket.engineio.client.transports.Polling.onData(Polling.java:101)
at io.socket.engineio.client.transports.PollingXHR$5$1.run(PollingXHR.java:109)
at io.socket.thread.EventThread$2.run(EventThread.java:80)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1137)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:637)
at java.lang.Thread.run(Thread.java:1012)
 
Top