HTTP library v1.5 - Asynchronous calls

Erel

Administrator
Staff member
Licensed 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

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

Administrator
Staff member
Licensed 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.basic4ppc.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

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.basic4ppc.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?
 

Erel

Administrator
Staff member
Licensed User
How do you send the data in the browser? As part of the URL?
If yes then you should use the default GET method instead of POST and just append the parameters to the URL.
 

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.
 

Erel

Administrator
Staff member
Licensed User
The code page parameter is not used. It was used in the one of the previous versions but currently it has no effect at all.
You should set the encoding of the BinaryFile object to the required encoding.
 

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;
}
 

Erel

Administrator
Staff member
Licensed User
V1.61 is attached with the new method.
Please tell me if it works as required.
 

Attachments

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.basic4ppc.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
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
 

Erel

Administrator
Staff member
Licensed User
You should use request.GetAsyncResponse instead of GetResponse. Then in the Response event you should call response.GetAsyncStream.

See the example in the manual: HTTP
 

konisek

Member
Licensed 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

Administrator
Staff member
Licensed 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
 

agraham

Expert
Licensed User
Sorry to jump in but shouldn't

response.Value = request.GetAsyncResponse

actually be

response.Value = request.AsyncResponse
 
Top