B4A Library WebSocket Client Library

Status
Not open for further replies.
This library allows you to create WebSocket connections with servers that support WebSockets.
It is based on this open source project: http://autobahn.ws/android/#

The main benefit of this library is that you can use it to communicate with B4J WebApp solutions.

The attached example includes a class named WebSocketHandler. With this class you can send events to the server and the server can send events to the device.

upload_2014-4-23_15-54-47.png


The server code is very simple:
B4X:
Sub Class_Globals
   Private ws As WebSocket
   Private timer1 As Timer
End Sub

Public Sub Initialize

End Sub

Private Sub WebSocket_Connected (WebSocket1 As WebSocket)
   ws = WebSocket1
   timer1.Initialize("timer1", 1000)
   timer1.Enabled = True
End Sub

Sub Timer1_Tick
'This method will raise the event on the device
   ws.RunFunction("ServerTime", Array As Object(DateTime.Time(DateTime.Now)))
   ws.Flush
End Sub

'event from the device
Sub Device_Message(Params As Map)
   Log("Device message: " & Params.Get("message"))
End Sub

Private Sub WebSocket_Disconnected
   timer1.Enabled = False
   Log("disconnected")
End Sub

Sending events to the server

WebSocketHandler.SendEventToServer takes the event name (not prefix in this case) and the data. The data is a Map that is converted to a JSON string. Note that the event name must include an underscore.

B4X:
Sub btnSend_Click
   Dim data As Map
   data.Initialize
   data.Put("message", EditText1.Text)
   wsh.SendEventToServer("Device_Message", data)
End Sub

Receiving events from the server

B4X:
Sub wsh_ServerTime(Params As List)
   'example of a server push message
   lblServerTime.Text = "Server Time: " & Params.Get(0)
End Sub

The sub name in this case is made of the prefix set in the Initialize method and the event name as received from the server. There should be a single parameter which is a List.

How to run this example?

You need the latest version of B4J: http://www.b4x.com/android/b4j.html
Download and run the server example.
You will need to open the firewall port (51042).

Set the address in the client code to match the server address.

Updates

v2.11: New Headers Map that can be used to add headers to the upgrade request (https://www.b4x.com/android/forum/threads/websocketclient-authorization.116574/#post-729213)
v2.10: New BinaryMessage event and SendBinary method.
v2.01: Fixes an issue with ssl disconnections that can throw the network on main thread exception.

v2.00: Based on the latest version of autobahn-java: https://github.com/crossbario/autobahn-java
Adds support for SSL connections (wss://) including using custom trust managers (mainly to accept self signed certificates).
SSL support is problematic on devices prior to Android 5. To support Android 4+ devices you need to update the security provider: https://www.b4x.com/android/forum/threads/ssl-websocket-client.88472/page-2#post-560044
 

Attachments

  • ServerExample.zip
    997 bytes · Views: 3,398
  • ClientExample.zip
    8.3 KB · Views: 3,821
  • WebSocket.zip
    39.6 KB · Views: 2,005
Last edited:

LucaMs

Expert
Licensed User
Longtime User
I'm re-reading this post.

The two server's routines have different scope!
The first, RunOnClient_NewNickOK, is private, the other is public.

The second is ran from a Module in which it is declared a map that contains the private rooms.

Maybe it will be sufficient to use CallSubDelayed, as in the Chatroom, but I can not understand why.


[P.S. using CallSubDelayed does not solve]
 
Last edited:

Reids

Member
Licensed User
Longtime User
Hello, I tried to create simple echo server, but client in basic4android cannot raise event when message received, web based client is received the message
what event for receiving the message? doc only say this lib only has 3 event

Connected
Closed (Reason As String)
TextMessage (Message As String)

but Onmessage does not have event, I also tried to use method as mentioned here
here the code
B4X:
Sub Timer1_Tick
'This method will raise the event on the device
   ws.RunFunction("ServerTime", Array As Object(DateTime.Time(DateTime.Now)))
   ws.Flush


but ws doesn't have ws.RunFunction :(

Thank You


EDITED:
Nevermind accidentially already found it

shuld call event manualy by
CallSub2(CallBack, "ws_TextMessage" & "_" & "onmessage", params)
 
Last edited:

Douglas Farias

Expert
Licensed User
Longtime User
1° its possible to connect multiple devices at same time at server?
2° all to list(Log) connected IPS,DEVICES on the server
3° its possible to close a connection for one ip?

All this questions is for a online game, the first its to know if can i use this to make a game online.
the second is to know how many users is playing my game, and the 3° its to know if can i ban a bad user from my gameserver.

thx
 

Reids

Member
Licensed User
Longtime User
1° its possible to connect multiple devices at same time at server?
2° all to list(Log) connected IPS,DEVICES on the server
3° its possible to close a connection for one ip?

All this questions is for a online game, the first its to know if can i use this to make a game online.
the second is to know how many users is playing my game, and the 3° its to know if can i ban a bad user from my gameserver.

thx
Hello we are on same boat, the based thing that I achieve so far is :
1.yes it possible, it is possible to connect multiple devices at the same time at the server
2.yes it possible, first you need to send parameter about ip session and device info thorough the header, after that server can read that info and save it as log
3.yes it possible, as I metioned above, all device information can be send over the header in handshake, just search specified ip then terminate it (server side code)

I also tried to developed online game with basic4android, but there are so many trouble
eg for mmorpg type game:
1. it is need hardcoded on server side to update only nearest character with player character
2. I recommended use native php code to server websocket so many example out there
3. you can make simple chatting apps first, if you can achieve that, it would be easier to achieve making online game
 

javiman6969

Member
Licensed User
Longtime User
Hi, Erel.

I'm trying to test this library, but can not I connect to a single server using node.js socket.io
I returned the message server disconnection "websockets connection lost" after clicking "Connect"

You could help me with some example of using connection with socket.io?

Thanks!!
 

javiman6969

Member
Licensed User
Longtime User
This server is in local network.
Using a server with node.js socket.io

A very basic code, to test the connection.
From a web client with javascript connects perfectly.


var io = require('socket.io').listen(8889); // server listens for socket.io communication at port 8889
//io.set('log level', 1); // disables debugging. this is optional. you may remove it if desired.

/io.sockets.on('connection', function (socket) {

console.log('receiving attempt to connect...');


socket.emit('log', { data: 'server connected' });


socket.on('commands', function (data) {

console.log(data);
Proccess_Commands(data);

});

socket.on('log', function (data) {

console.log(data);


});


socket.on('disconnect', function () {
console.log('disconnected from client');
});
});
 

javiman6969

Member
Licensed User
Longtime User
socket.io may support other protocols as well as WebSocket.

You can easily create a WebSocket server with B4J and test it.

Hi Erel
Yes, it is true, but the device where the server runs is an Arduino Yun (Linux: Linino) and I need to be a server with socket.io and node.js
There would be some way to make it work with that?
 

TAK

Member
Licensed User
Longtime User
Hello,
sorry, i have some beginner questions.
What is "Sub WebSocket_Connected" doing? Why do we need a timer? And why do we need StartMessageLoop? What is StartMessageLoop for a function?

Thx
 
Status
Not open for further replies.
Top