B4J Question [ xHttpServer ] How to listen to websockets messages sent by the client, without having to create a "click event or something like that"?

Waldemar Lima

Well-Known Member
Licensed User
Hi @Star-Dust

on B4J
I'm using a Webview + xHttpServer to create a webapp... is it possible to send and receive messages from the websocket client to the xHttpServer?

my code >

B4X:
#Region Shared Files
#CustomBuildAction: folders ready, %WINDIR%\System32\Robocopy.exe,"..\..\Shared Files" "..\Files"
'Ctrl + click to sync files: ide://run?file=%WINDIR%\System32\Robocopy.exe&args=..\..\Shared+Files&args=..\Files&FilesSync=True
#End Region

'Ctrl + click to export as zip: ide://run?File=%B4X%\Zipper.jar&Args=Project.zip

Sub Class_Globals
    Private Root As B4XView
    Private xui As XUI
    Private WebView1 As WebView
    Private Svr As httpServer
    Private counter As Int = 0
End Sub

Public Sub Initialize
'    B4XPages.GetManager.LogEvents = True
End Sub

'This event will be called once, before the page becomes visible.
Private Sub B4XPage_Created (Root1 As B4XView)
    Root = Root1
    Root.LoadLayout("MainPage")
   
    Svr.Initialize(Me,"Svr")
    Svr.Start(51051)
    WebView1.LoadUrl("http://127.0.0.1:51051")
   
End Sub

Private Sub Svr_NewConection(req As ServletRequest)
    Log("New connection: " & req.RemoteAddress )
End Sub

' Handle websocket request
Private Sub Svr_SwitchToWebSocket (req As ServletRequest, resp As ServletResponse)
    Select req.GetRequestURI
        Case "/browser/ws"
            Log("Svr_SwitchToWebSocket /browser/ws")
           
    End Select
End Sub

Private Sub Svr_HandleWebSocket (req As ServletRequest, resp As ServletResponse)
    Log("asdasdas")
   
    Select req.GetRequestURI
        Case "/browser/ws"
            Log("Svr_HandleWebSocket  /browser/ws")
           
           
           
    End Select
End Sub

Private Sub Svr_WebSocketClose(CloseCode As Int, CloseMessage As String)
    Log($"Closed: ${CloseCode} -  Error: ${CloseMessage}"$)
End Sub

Private Sub Svr_Handle(req As ServletRequest, resp As ServletResponse)
    Dim URI As String = req.GetRequestURI
    Log($"Request (${req.ID}) URI: "$ & req.GetRequestURI)
   
    If req.GetRequestURI="/" Or req.GetRequestURI="/index.html"  Then
        resp.ContentType = "text/html"
        resp.SendString($"
       
        <!doctype html>
        <html>
            <head>
                <meta charset="UTF-8">
                <title>Guess My Number - with web sockets!!!</title>
                <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.js"></script>
                 <script src="/b4j_ws.js"></script>
            </head>
            <body>
            <div style="margin-left: 50px;">
            <h1>Guess My Number - with web sockets!!!</h1>
            Enter number: <input type="text" id="txtnumber"></input>
            <button type="button" id="btnguess">Guess!</button><br/><br/>
            <button type="button" id="btnreset">Reset secret number</button><br/>
            <p id="result"></p>
            <p id="servertime">Server time: </p>
            <script>
            $(document).ready(function() {
                b4j_connect("/browser/ws");          
            });
            </script>
            </div>
             </body>
        </html>
       
        "$)
    Else If (req.GetRequestURI="/b4j_ws.js") Then
        resp.ContentType = "application/javascript"
        resp.SendString($"
       
            //B4J WebSockets client library v0.9

            /*jslint browser: true*/
            /*global $, jQuery, WebSocket*/
            /*jshint curly: false */
            "use strict";
            var b4j_ws;
            var b4j_closeMessage = false;
            //only called as a result of a server request that is waiting for result.
            //this method should not be called in any other case.
            function b4j_sendData(data) {
                b4j_ws.send(JSON.stringify({type: "data", data: data}));
            }
            function b4j_raiseEvent(eventName, parameters) {
                try {
                    if (b4j_ws.readyState !== 1) {
                        if (b4j_closeMessage === false) {
                            window.console.error("connection is closed.");
                            window.alert("Connection is closed. Please refresh the page to reconnect.");
                            b4j_closeMessage = true;
                        }
                    } else {
                        b4j_ws.send(JSON.stringify({type: "event", event: eventName, params: parameters}));
                    }
                } catch (e) {
                    window.console.error(e);
                }
            }
            function b4j_addEvent(selector, event, eventName, preventDefault) {
                var obj = $(selector);
                if (obj.length > 0) {
                    obj.on(event, function (e) {
                        if (preventDefault) {
                            e.preventDefault();
                            e.stopPropagation();
                        }
                        b4j_raiseEvent(eventName, {which: e.which, target: e.target.id, pageX: e.pageX, pageY: e.pageY, metaKey: e.metaKey});
                    });
                }
            }
            function b4j_addAutomaticEvents(data) {
                $.each(data, function (index, value) {
                    b4j_addEvent("#" + value.id, value.event, value.id + "_" + value.event, true);
                });
            }
            function b4j_runFunction(func, params) {
                return window[func].apply(null, params);
            }

            function b4j_eval(params, script) {
                var f = new Function(script);
                return f.apply(null, params);
            }

            function b4j_connect(absolutePath) {
                if (typeof WebSocket === 'undefined') {
                    window.alert("WebSockets are not supported by your browser.");
                    return;
                }
                var l = window.location, fullpath;
                fullpath = ((l.protocol === "https:") ? "wss://" : "ws://") + l.hostname + ":" + l.port + absolutePath;
                b4j_ws = new WebSocket(fullpath);
                b4j_ws.onmessage = function (event) {
                    var ed = JSON.parse(event.data);
                    if (ed.etype === "runmethod") {
                        $(ed.id)[ed.method].apply($(ed.id), ed.params);
                    } else if (ed.etype === "runmethodWithResult") {
                        b4j_sendData($(ed.id)[ed.method].apply($(ed.id), ed.params));
                    } else if (ed.etype === "setAutomaticEvents") {
                        b4j_addAutomaticEvents(ed.data);
                    } else if (ed.etype === "runFunction") {
                        b4j_runFunction(ed.prop, ed.value);
                    } else if (ed.etype === "runFunctionWithResult") {
                        b4j_sendData(b4j_runFunction(ed.prop, ed.value));
                    } else if (ed.etype === "eval") {
                        b4j_eval(ed.value, ed.prop);
                    } else if (ed.etype === "evalWithResult") {
                        b4j_sendData(b4j_eval(ed.value, ed.prop));
                    } else if (ed.etype === "alert") {
                        window.alert(ed.prop);
                    }
                   
                };
            }

        "$)
       
    End If
   
End Sub

'You can see the list of page related events in the B4XPagesManager object. The event name is B4XPage.

Private Sub Button1_Click
    xui.MsgboxAsync("Hello world!", "B4X")
End Sub
 

Star-Dust

Expert
Licensed User
Longtime User
Here you will find an example to use webSocket
 
Upvote 0

Waldemar Lima

Well-Known Member
Licensed User
Here you will find an example to use webSocket
From what I understood from the websocket example, it is necessary to register Events in iQuery. I don't know how to have a handler to listen to raw messages.
 
Upvote 0

Star-Dust

Expert
Licensed User
Longtime User
Yes, unlike the normal JQuery library, mine has to log events on a per-page basis (HTML)
 
Upvote 0
Top