HTTP library v1.5 - Asynchronous calls

Erel

B4X founder
Staff member
Licensed User
Longtime User
HTTP library v1.5 is attached.
The new version adds support for asynchronous calls.
You can now use Request.GetAsyncResponse to send a request to a server and get the response without blocking the main program.
When the response is available the Response event will be fired.

The response stream could also be asynchronously downloaded with Request.GetAsyncStream which downloads the stream to a temporary (or not temporary) file, or Request.GetAsyncString which builds a string out of the response. In both cases the Stream event will be fired when the process finishes retrieving the stream.
It is also possible to cancel the process and get the number of bytes downloaded (to show the progress).
The manual is available online: HTTP

Setup instructions:
- Download the zip file.
- Extract and copy HTTP.dll (library), HTTP.cs (code for merging) and HTTP.CHM (help file) to Basic4ppc folders library:
C:\Program Files\Anywhere Software\Basic4ppc Desktop\Libraries

Also replace existing copies of http.dll in the source code folder.
 

Attachments

  • HTTP.zip
    30.7 KB · Views: 448

Elrick

Member
Licensed User
Erel, can you show a simple example how can i POST data and get the response using asynchronous calls? I'm a bit stuck... Thanks
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
I'm using a simple php file that prints the POST variables.
B4X:
Sub Globals

End Sub

Sub App_Start
    Form1.Show
End Sub

Sub Button1_Click
    request.New1("http://www.b4x.com/print.php")
    request.Method = "POST"
    Request.ContentType = "application/x-www-form-urlencoded"
    stream.New1(Request.GetStream,True) 
    name = "First=Erel&Last=Uziel"
    stream.WriteBytes(stream.StringToBytes(name))
    response.New1
    request.GetAsyncResponse
End Sub

Sub request_Response
    If request.ResponseCode = 200 Then
        response.Value = request.AsyncResponse
        response.GetAsyncString
    Else
        Msgbox(request.ErrorMessage)
    End If
End Sub

Sub response_Stream
    TextBox1.Text = response.AsyncString
End Sub
 

Attachments

  • HTTP-POST.sbp
    1 KB · Views: 99

Elrick

Member
Licensed User
Thanks Erel, i've found where i made a mistake. There are many new methods in this lib, i've became puzzled a bit:)
 

Aspire89

Member
Licensed User
Hello all. The task of the next.
We need to send to the server request to view: http://site.com/page.php?lat=56.565&lng=58.424
use the following code:
B4X:
request.New1("[URL="http://www.b4x.com/forum/print.php"]http://site.com/page.php[/URL]")
request.Method = "POST"
Request.ContentType = "application/x-www-form-urlencoded"
stream.New1(Request.GetStream,True) 
name = "[URL="http://site.com/page.php?lat=56.565&lng=58.424"]lat=56.565&lng=58.424[/URL] "
stream.WriteBytes(stream.StringToBytes(name))
response.New1
request.GetAsyncResponse
but the server does not receive the data lat=56.565&lng=58.424
script which is on the server:
PHP:
$data=file_get_contents('data.xml');
$data=str_replace("</markers>", "", $data);
$fd=fopen('data.xml', "w+");
fwrite($fd, $data);
fwrite($fd, '<marker lat="' . $_GET['lat'] . '" lng="' . $_GET['lng'] . '"/>');
fwrite($fd, "\n");
fwrite($fd, '</markers>');
fclose($fd);
and a sample xml file:
B4X:
<markers>
<marker lat="58.0057450" lng="56.2401117"/>
<marker lat="58.0064167" lng="56.2426733"/>
<marker lat=[B]""[/B] lng=[B]""[/B]/>
</markers>
if you send a request through the browser then everything is OK, but if the program is a string with empty values of lat and lng in the xml file, how can we solve this problem?
 

Aspire89

Member
Licensed User
I use request.New3(url, User, Pass), and requires an additional change code page encoding. How can this be done? Tried through door.dll library, but fails.

Thanks.
 

chanppc

Member
Licensed User
Can I request to have domain name in the SetProxy? I noted I need to customize the dll when connect from company network which used some sort of AD authentication. Thanks.

public void SetProxy3(string Host, int PortNumber, bool BypassOnLocal, string Username, string Password, string Domain)
{
WebProxy w = new WebProxy(Host, PortNumber);
w.Credentials = new NetworkCredential(Username, Password, Domain);
w.BypassProxyOnLocal = BypassOnLocal;
GlobalProxySelection.Select = w;
}
 

chanppc

Member
Licensed User
My apps require trigger multiple http download & I'm hit with occassionaly "timeout -1" problems on device, strange that it doesn't happen on desktop.

Upon a search on forum, I noted quite a numbers of forumer reported such issue & some solution is to extend the timeout.

But now I realized the actual problem, I was following the sample in the help file for both GetAsyncString & GetAsyncStream, & it does not include response.close, which may cause problem when initiate the 2nd download, which causes timeout, but most likely will success again when try for the 3rd time.

You may want to include it in the sample in yr next release ;)

---------------

//GetAsyncString

Sub Globals
URL = "http://www.b4x.com"
End Sub


Sub App_Start
Form1.Show
request.New1(URL)
response.New1
request.GetAsyncResponse
End Sub


Sub request_Response
If request.ResponseCode = 200 Then '200 is the code of successful connections.
response.Value = request.AsyncResponse
response.GetAsyncString
Else
Msgbox("Error getting response: " & request.ErrorMessage & CRLF _
& "Response code: " & request.ResponseCode)
End If
End Sub


Sub response_Stream
response.close
TextBox1.Text = response.AsyncString
End Sub
 

konisek

Member
Licensed User
Longtime User
syncrhonous -> asynchronous call

I use the foolowing code:
B4X:
Sub Button1_Click
....
response.New1
request.New1 (URL)
request.Method = "POST"
request.TimeOut = 60000
request.ContentType = "application/x-www-form-urlencoded"

stream.New1(Request.GetStream,True)
stream.WriteBytes(stream.StringToBytes(name))
response.Value = request.GetResponse

'reading cookie
regex.New1("PHPSESSID=.[a-zA-Z0-9]+")
match.New1
match.Value = regex.Match(response.Headers)
Session_ID = match.String

'Get the response into array
bin.New1(response.GetStream, True)
bit.New1
Dim buffer(1024) As byte
count = bin.ReadBytes(buffer(),1024)
For i = 0 To ArrayLen(buffer())-1
retezec = retezec & " " & buffer(i)
Next 
Msgbox(retezec)

'operations with buffer()
....
TextBox4.Text = bit.BytesToString(buffer(), 4, count)
response.Close
End Sub
Can you, please, advise how to use the asynchronous calls, esp. with respect to cookie? I read the response into array rather than
B4X:
TextBox4.Text = Response.GetString
 

konisek

Member
Licensed User
Longtime User
Yes, I have tried it. It gives me a NullReferenceException Error in match.Value = regex.Match(response.Headers)
But I suppose that my structure is not correct:
B4X:
Sub Button1_Click
....
response.New1
request.New1 (URL)
request.Method = "POST"
request.TimeOut = 60000
request.ContentType = "application/x-www-form-urlencoded"

stream.New1(Request.GetStream,True)
stream.WriteBytes(stream.StringToBytes(name))
[COLOR="Red"]request.GetAsyncResponse[/COLOR]

'reading cookie
regex.New1("PHPSESSID=.[a-zA-Z0-9]+")
match.New1
match.Value = regex.Match(response.Headers)
Session_ID = match.String

'operations with buffer() [COLOR="Blue"]'Here I want to use the buffer from response_Stream[/COLOR]
....
TextBox4.Text = bit.BytesToString(buffer(), 4, count)
response.Close
End Sub

Sub request_Response
response.Value = [COLOR="Red"]request.GetAsyncResponse[/COLOR]
[COLOR="Red"]response.GetAsyncStream[/COLOR]
End Sub

Sub response_Stream  [COLOR="Blue"]'Here I want to read the response and put it to array. And then I want to use it in  Sub Button1_click[/COLOR]
'Get the response into array
bin.New1(response.GetStream, True)
bit.New1
Dim buffer(1024) As byte
count = bin.ReadBytes(buffer(),1024)
For i = 0 To ArrayLen(buffer())-1
retezec = retezec & " " & buffer(i)
Next 
Msgbox(retezec)
End Sub
 
Last edited:

Erel

B4X founder
Staff member
Licensed User
Longtime User
The response object is only available after this line:
B4X:
response.Value = request.GetAsyncResponse

So your code should look something like:
B4X:
...
request.GetAsyncResponse
End Sub

Sub request_Response

response.Value = request.GetAsyncResponse
regex.New1("PHPSESSID=.[a-zA-Z0-9]+")
match.New1
match.Value = regex.Match(response.Headers)
Session_ID = match.String
...

About the stream, see the manual for an example of using Response.GetAsyncStream: HTTP
 
Top