B4J Question Servlet versus Websocket?

johnerikson

Active Member
Licensed User
Longtime User
A simple question about Servlet versus Websocket, maybe stupid.
What corresponds to the ServletResponse. (Resp.write) in Websocket?


Sub Handle(req AsServletRequest, resp AsServletResponse)
Dim shl AsShell
shl.Initialize( "shl", "c:\php\php.exe", ArrayAsString("getalbumpics.php","?ID=Start"))
shl.WorkingDirectory = "E:\Program\B4J\Server\AppServer\Objects\www\php\images"
Dim res AsShellSyncResult = shl.RunSynchronous(10000)
Resp.Write(res.StdOut) ‘Works fine!
EndSub

How do you do Resp.write in Wbesocket or is it impossible?

PrivateSub WebSocket_Connected (WebSocket1 AsWebSocket)
ws = WebSocket1
Dim shl AsShell
shl.Initialize( "shl", "c:\php\php.exe", ArrayAsString("getalbumpics.php","?ID=Start"))
shl.WorkingDirectory = "E:\Program\B4J\Server\AppServer\Objects\www\php\images"
Dim res AsShellSyncResult = shl.RunSynchronous(10000)
ws.What ??? something like ws.write (res.StdOut)
ws.Flush
EndSub
 

Roycefer

Well-Known Member
Licensed User
Longtime User
There's no easy equivalent in a WebSocket but you can raise an event on the client side by calling ws.RunFunction(). You can also run arbitrary JavaScript code on the client by calling ws.Eval(). These are some ways you can communicate a message to the client, which is what Resp.Write() does with a Handler.
 
Upvote 0

johnerikson

Active Member
Licensed User
Longtime User
THANKS!
I'm trying to get the proposal to work without result!
I use Chrome browser! Windows 10
I have no HTML5 app, only a html file (index.html)
I wonder what function ClientGetsString (code;?), do

I have added the following in the index.html
<script>
$( document ).ready(function() {
b4j_connect("/php");
});
function ClientGetsString() {
what to do? Here?
//window.alert("Called"); // this test work if activated
}
b4j_raiseEvent("fromUser_LogThisString", {sample:"This is a sample message sent from the client"});
</script>

And added the code in the class module, WS:
ws. RunFunction ("ClientGetsString", Array ("this is a sample message sent from the server"))
and
Sub fromUser_LogThisString (params As Map)
Dim sampleString As String = params.
Get ("sample") Log ("Sample String:" & sampleString)
End Sub

nothing happens ! Whats wrong?
 
Upvote 0

Roycefer

Well-Known Member
Licensed User
Longtime User
In your server code, is your WebSocketClass module called "php"? Because that's to what you are connecting in your b4j_connect() call in your JavaScript code. Also, have you placed a <script src="b4j_ws.js"></script> line your HTML file? You'll need that for B4J WebSockets to work, as well as hosting the b4j_ws.js file in your statics folder.
 
Upvote 0

johnerikson

Active Member
Licensed User
Longtime User
I can get b4j_raiseEvent to work, but the main problem is to make a resp.write function (from handle abowe) in the Websocket class.
"getalbumpics.php" is running a feature that delivers a string of data as response on a request. This works with resp.write (response) under handle class

If I run the same function with the WebSocket class, I get the same data from the "getalbumpics.php" but I cannot send the response back as with resp.write in handle class.
I'm wondering about what I'm missing, I think it is the code for function ClientGetsString () you mention, that is JavaScript code that emulates resp.write. I have searched for hours but failed to find an example of such a function written in javascript.
If I do not get clarity in this problem I have to do a reprogramming of the management of image editing that I'm working with just now!

It may not be easy to understand what I mean because of my poor wording in English!
 
Last edited:
Upvote 0

Roycefer

Well-Known Member
Licensed User
Longtime User
The JavaScript function ClientGetsString() should look like this:
B4X:
function ClientGetsString(inString)
{
   //do something interesting with the argument inString, for example:
   console.log("String received: " + inString);
}
You can do anything you want inside the ClientGetsString. The point of that function is that it accepts a single argument and that argument is the String sent by the server. This is how you can send Strings to WebSocket clients.
 
Upvote 0

johnerikson

Active Member
Licensed User
Longtime User
I have tested console.log (inString). I can see in the browser's inspection window that string coming out of the log. But it does not react in exactly the same way as Serverletresponse. The answer not reach ddphpalbum.js (see sketch.ppt).

I use two third-party products which is why I think the best thing is to give up. I'm working on with the Handle class that works. It is sad because it is much easier to communicate html and JavaScript with Websocket.

I am impressed with your support but don't want to use too much time from you. Maybe answer some questions.

Is it possible to create and manage event in handle-class?
Somthing equivalent to ws. runfunction in handle-class?
Start a sub in handle-class from the Html?

There are certainly answers in online support but it is large and you had to spend many hours to get right! The hardest thing is to separate the responses from all the different products and variations, but it is very valuable!
 

Attachments

  • sketch.PNG
    sketch.PNG
    51.3 KB · Views: 306
Upvote 0

Roycefer

Well-Known Member
Licensed User
Longtime User
You can create subs in a Handler class and they can be called from the Handle sub. You can invoke a Handler class by sending a GET request or a POST request from HTML in the normal fashion. As for creating and managing events in a Handler class, I don't think this is a reliable scheme. Keep in mind that the Handler class will execute the Handle sub and once the Handle sub returns, it will pass out of scope (regardless of what thread it is in) and the instance will be garbage collected. The next time that Handler is invoked, a new instance will be created, not knowing anything about a previous instance (unless you stored state information in a global variable declared in Main). If you want a long-lived object that has a long-lived connection to the client, WebSockets is the way to go. They execute in their own thread, have their own event loops, etc...

I'm not sure what your third-party JavaScript is doing but if it's just downloading pictures, you can do this with GET requests on a static asset. You can use the ClientGetsString() method (or one like it) to send the relative URL of a picture you want the client to download and then inside that method, execute a GET request on that relative URL. Just make sure the picture is at the relative URL you're sending (it will be in your statics folder).

Otherwise, if there's some function inside ddphpalbum.js that is supposed to be executed, you could call that function directly from inside ClientGetsString(). Or you can call it directly from the WebSocket class. You can call any JavaScript method or execute any arbitrary JavaScript from within the WebSocket class.
 
Upvote 0

johnerikson

Active Member
Licensed User
Longtime User
A lot of thanks!
I have material to work with, I run to see if the next stop will be.
Web development is an exciting new area for me, B4X making it relatively easy to get started!
 
Upvote 0
Top