Other Web Apps based on WebSocket are coming...

Erel

B4X founder
Staff member
Licensed User
Longtime User
B4J allows you to build backend web servers with the server library.

Http web servers response to client requests. The communication is always made of a client request followed by a browser response. This method is very powerful however it is not simple when it comes to handling user interaction.

WebSocket is a relatively new protocol that makes it possible to create a full duplex connection between the client and the server and keep this communication channel open.
http://en.wikipedia.org/wiki/WebSocket

B4J v2.00 together with WebSocket will make it much simpler to develop web applications.
The UI will be written with Html and CSS and the logic will be implemented on the server.
The solution will be highly extensible. It will be very simple to combine JavaScript code and other JavaScript frameworks.

As a very first example you can try this "guess my number" app:
http://basic4ppc.com:51042/guessmynumber_ws/


The code:
B4X:
'Class module
Sub Class_Globals
   Private ws As WebSocket
   Private myNumber As Int
   Private timer1 As Timer
   'these variables will be set automatically.
   Private jqTxtNumber As JQueryElement 'matches an element with id = "txtnumber"
   Private jqResult As JQueryElement
   Private jqServerTime As JQueryElement
End Sub

Public Sub Initialize
   myNumber = Rnd(1, 101)
End Sub

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

Private Sub WebSocket_Disconnected
   timer1.Enabled = False
End Sub

Sub btnGuess_Click (Params As Map)
   Dim s As Long = DateTime.Now
   Dim number As String = jqTxtNumber.GetVal.Value
   If IsNumber(number) Then
     Dim n As Int = number
     If n > myNumber Then
       jqResult.SetHtml("My number is smaller.")
     Else If n < myNumber Then
       jqResult.SetHtml("My number is larger.")
     Else
       jqResult.SetHtml("<b>Well done!!!</b>")
     End If
   Else
     jqResult.SetHtml("Please enter a valid number.")
   End If
   jqTxtNumber.RunMethod("select", Null)
   Log(ws.UpgradeRequest.RemoteAddress & ": " & (DateTime.Now - s))
End Sub

Sub Timer1_Tick
   jqServerTime.SetHtml("Server time: " & DateTime.Time(DateTime.Now))
   ws.Flush 'required here as this is a server event
End Sub

Sub txtNumber_KeyUp(Params As Map)
   If Params.Get("which") = 13 Then
     btnGuess_Click (Null)
   End If
End Sub

Sub btnReset_Click (Params As Map)
   myNumber = Rnd(1, 101)
End Sub

The html code:
SS-2014-04-01_18.03.35.png


This is all of the code (except of 3 lines to start the server). The events are bound automatically. You do not need to know JavaScript in order to use it.

As you can see in this code it "directly" interacts with the html elements. It is quite similar to interacting with a standard UI though the network latency should be considered.

Most browsers already support the WebSocket protocol: http://caniuse.com/websockets
Android 4+ supports WebSocket with the Chrome browser.

Beta testers

If there are any members who would like become beta testers then please contact me by mail: [email protected].

As with any new feature, your feedback is very important...
 
Last edited:

Erel

B4X founder
Staff member
Licensed User
Longtime User
Moving smiley example:

SS-2014-04-08_13.07.17.png


Online: http://basic4ppc.com:51042/smiley/index.html

It uses HTML5 Canvas object to draw and move the image.
The main code is:
B4X:
Sub Timer1_Tick
   ws.RunFunction("ClearRect", Array As Object(x, y, boxSize, boxSize))
   If x  + boxSize > cvsWidth Then
     vx = -1 * Abs(vx)
   Else If x < 5 Then
     vx = Abs(vx)
   End If
   If y  + boxSize > cvsHeight Then
     vy = -1 * Abs(vy)
   Else If y < 5 Then
     vy = Abs(vy)
   End If
   x = x + vx
   y = y + vy
   ws.RunFunction("DrawImage", Array As Object(x, y))
   ws.Flush
End Sub

You can see that the movement is quite smooth.
The reason for that is that the server only sends commands to the browser during the movement, so the network latency doesn't slows it down.
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
Dynamic controls example:

SS-2014-04-08_15.27.38.png


Online example: http://basic4ppc.com:51042/dynamic/

The code is quite simple. It creates 100 buttons when the WebSocket is connected. By handling the click event of the div parent we can easily handle the events of the dynamic buttons.
Code:
B4X:
Sub Class_Globals
   Private ws As WebSocket
   Private MainDiv As JQueryElement
   Private plog As JQueryElement
   Private buttonsText As Map
End Sub

Public Sub Initialize
End Sub

Private Sub WebSocket_Connected (WebSocket1 As WebSocket)
   ws = WebSocket1
   buttonsText.Initialize
   Dim base As String = File.ReadString(File.DirAssets, "Dynamic.html")
   Dim sb As StringBuilder
   sb.Initialize
   For y = 0 To 9
     For x = 0 To 9
       Dim id As String = "btn" & (y * 10 + x)
       buttonsText.Put(id, 0)
       sb.Append(WebUtils.ReplaceMap(base, _
         CreateMap("ID": id, _
           "LEFT": x * 50, _
           "TOP": y * 50, _
           "TEXT": "0")))
     Next
   Next
   MainDiv.SetHtml(sb.ToString)
End Sub

Sub MainDiv_Click (Params As Map)
   'find the target element
   Dim target As String = Params.Get("target")
   If target.StartsWith("btn") Then
     plog.SetHtml("Button <i>" & target & "</i> was clicked")
     Dim btn As JQueryElement = ws.GetElementById(target)
     'get the current value from the map.
     Dim counter As Int = buttonsText.Get(target) + 1
     btn.SetText(counter)
     buttonsText.Put(target, counter)
     btn.SetCSS("background-color", RandomCSSColor)
   End If
End Sub

Sub RandomCSSColor As String
   Return "rgb(" & Rnd(0, 256) &"," & Rnd(0, 256) &"," & Rnd(0, 256) & ")"
End Sub

The template file:
B4X:
<button id="$ID$" style="position: absolute; left: $LEFT$px; top: $TOP$px; width: 45px; height: 45px;">$TEXT$</button>
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
A new example is online: file upload with web sockets. This example is interesting as it combines a handler with websocket module. The handler receives the file and calls the websocket when the file is ready:
Handler code:
B4X:
Sub Handle(req As ServletRequest, resp As ServletResponse)
   'get the callback module from the session (multiple modules can use this handler)
   Dim callback As Object = req.GetSession.GetAttribute("file_upload_sender")
   Try
     Dim data As Map = req.GetMultipartData(Main.TempDir, 100000)
     CallSubDelayed2(callback, "FileUploaded", data)
   Catch
     CallSubDelayed2(callback, "FileError", LastException.Message)
     resp.SendError(500, LastException.Message)
   End Try
End Sub

WebSocket code:
B4X:
Private Sub WebSocket_Connected (WebSocket1 As WebSocket)
   ws = WebSocket1
   form1.RunMethod("ajaxForm", Null)
   ws.Session.SetAttribute("file_upload_sender", Me)
End Sub

Public Sub FileUploaded(parts As Map)
   Dim filePart As Part = parts.Get("file1")
   Result.SetText("File uploaded successfully: " & filePart.SubmittedFilename & _
     " size = " & NumberFormat(File.Size("", filePart.TempFile) / 1000, 0, 0) & "kb")
   Result.SetCSS("color", "black")
   File.Delete("", filePart.TempFile)
   ws.Flush 'this is a server event so we need to explicitly call Flush
End Sub

The http session is the key here. All user requests share the same session, so the web socket stores a reference to itself in the session which is later used by the handler to "raise an event".

Note that all the examples are available here: http://basic4ppc.com:51042/

The server library now supports SSL connections (https).
Hopefully the first beta will be released tomorrow.
 
Upvote 0
Top