HttpUtils - how to send a command which doesn't generate a return-value?

moster67

Expert
Licensed User
Longtime User
I got most of my old http-code ported to be used successfully with HttpUtils however I am stuck with one issue.

Within my code I am executing a command that will not generate a reply in return from the server. The command is similar to the one below:

B4X:
http://192.168.1.5:8888/cgi-bin/zapTo?path=123456

The command is being sent to the server and the supposed action on the server is successful however HttpUtils never raises the job-done event probably because it is waiting for a return-value from the server. As a matter of fact, successive attempts using the same command generate an error saying that the previous job has not yet finished.

Can someone please let me know how to modify the HttpUtils-code so HttpUtils doesn't sit there awaiting a response so I can proceed with other commands (jobs). Ideal would be perhaps adding a method to permit it since I use all the other methods for other requests (where I do expect a return-value from the server). Alternatively, I could perhaps handle it with a flag but then I would need to know how to force the job-done event as successful.

I guess I could use the old http-code but it would be nice to be using HttpUtils for all my needs without using the old code for this single problem.

Any help I can get would be appreciated. Thanks!
 

moster67

Expert
Licensed User
Longtime User
Yes, I am pretty sure the server does not reply. This is probably due to the fact that the server is a satellite-receiver (rather old firmware) and the webservice for this command in particular does not issue a response since the command is only used to change a channel. Newer firmware does issue a reply whether the command was successful or not. In any case, in my previous working http-code I used:

B4X:
request.InitializeGet(URLZap)

If HttpChanClient1.ExecuteCredentials(request,2,main.BoxUser,main.BoxPassword)=False Then Return

and then I received an OK in the following sub

B4X:
Sub HttpChanClient1_ResponseSuccess (Response As HttpResponse, TaskId As Int)

If taskid=2 Then
     'my successive code
End If

end sub

My problem using HttpUtils is that my code get "trapped" in the inner workings of HttpUtils so I cannot proceed with successive jobs probably becasue HttpUtils expects a return from the server while using my old code cited above this will not happen.

Probably the way HttpUtils has been structured is to wait for a reply. If I somehow, perhaps using a flag, could force the JobDone-event, that would be great. Is this possible?
 
Upvote 0

ramil

New Member
Licensed User
Longtime User
Firefox and IE surfing

Hi,

I'm also looking for a simple solution, and I think we share the same issue.

I need to make my android app surfing to "192.168.1.60/t1"
and like moster67 , I will get an answer from the web, but I don't really needs the answer.

I'm trying to implement surfing to the above link like using explorer or Firefox, this browsing to the specific link shell switch a led in my micro-controller mini web board.

Is it simple to implement?

Erel explanation was to hard for beginner like me. Even so I did try to change the HttpUtils example, but with no success.

Thank You.
 
Upvote 0

moster67

Expert
Licensed User
Longtime User
@ramil

I resolved it by modifying the code as follows:

in the Http Utils module:

I modified the Download-sub as follows (adding a SkipResponse-boolean/flag):

B4X:
Sub Download(JobName As String, URL As String,SkipResponse As Boolean)
   If SkipResponse = True Then
   HttpUtilsService.SkipResponse=True
   End If
DownloadList(JobName, Array As String(URL))
End Sub

in the Http UtilsService module:

I added the boolean SkipResponse in the Sub Process_Globals like this:

B4X:
Dim SkipResponse As Boolean

then I modified the Sub hc_ResponseSuccess as follows:

B4X:
Sub hc_ResponseSuccess (Response As HttpResponse, TaskId As Int)
   If SkipResponse = True Then
   Response_StreamFinish(True,0)
   SkipResponse=False
   Else
   Response.GetAsynchronously("response", File.OpenOutput(TempFolder, TaskId, False), _
      True, TaskId)
   End If
End Sub

To use it, I simply call

B4X:
If main.EnigmaType="Enigma" Then 
   HttpUtils.Download("JOB_ZAPTO",URLZap,True) 'True=no response wanted
Else
   HttpUtils.Download("JOB_ZAPTO",URLZap,False) 
End If

This works for me and I can still use the HttpUtils-module instead of using the "old" way.
 
Last edited:
Upvote 0

moster67

Expert
Licensed User
Longtime User
BTW: if your web-server does return a response, then the original Http Utils-module should work as Erel says but in my case no response is being issued by the server and the Response.GetAsynchronously-code just hangs so I need to skip it.
 
Upvote 0

ramil

New Member
Licensed User
Longtime User
Working... but....

Hi,

My app it working great now, I've created a simple graphical interface that surf my mini web (microchip) so pressing a button in the GUI shall turn a small led or motor on and off.

But I have a strange problem...

My tablet hangs up or resets itself when my application is running. this happens randomly and can happen just after the app is started or after a day or even two days!

it is very small and simple app based on the httpUtils and httputilsService example.

Did I do something wrong ?

Your help is very appreciated!

MAIN
B4X:
  Sub Globals
 Dim b4a As String
 '--------------------------------------
 b4a = "http://192.168.1.60"
 '--------------------------------------
 bt1  = "http://192.168.1.60/c1" 'led1"  
 bt2  = "http://192.168.1.60/c2" 'led1 off" 
 
 bt3  = "http://192.168.1.60/c3"  
 bt4  = "http://192.168.1.60/c4" 
 
 bt5  = "http://192.168.1.60/c5"  'motor down"
 bt6  = "http://192.168.1.60/c6"  'motor up"
 
 bt7  = "http://192.168.1.60/c7"  'led2 up"
 bt8  = "http://192.168.1.60/c8"  'led2 down"
 
 bt9  = "http://192.168.1.60/t3"   
 bt10 = "http://192.168.1.60/t2"  
 bt11 = "http://192.168.1.60/t1"  
 '------------------------------------
 bt111 = "http://192.168.1.60/k3"
 bt112 = "http://192.168.1.60/k2"
 bt113 = "http://192.168.1.60/k1" 
 bt114 = "http://192.168.1.60/k0" 
 '------------------------------------
 bt115 = "http://192.168.1.60/d2"   
 bt116 = "http://192.168.1.60/d1" 
 bt117 = "http://192.168.1.60/d0"  
 
   Dim Button1 As Button
   Dim EditText1 As EditText
   Dim Button2 As Button
End Sub
Sub Activity_Create (FirstTime As Boolean)
Activity.LoadLayout("view1")
 HttpUtils.CallbackActivity = "Main" 'Current activity name.
 HttpUtils.CallbackJobDoneSub = "JobDone"
 HttpUtils.Download("Job1", b4a)
End Sub

Sub JobDone (Job As String)
 Dim s As String
 If HttpUtils.IsSuccess(b4a) Then
  EditText1.Text = HttpUtils.GetString(b4a)
 End If
End Sub

Sub Button1_Click
 HttpUtils.CallbackActivity = "Main" 'Current activity name.
 HttpUtils.CallbackJobDoneSub = "JobDone"
 HttpUtils.Download("Job1", bt1)   
End Sub

Sub Button2_Click
 HttpUtils.CallbackActivity = "Main" 'Current activity name.
 HttpUtils.CallbackJobDoneSub = "JobDone"
 HttpUtils.Download("Job1", bt2)
 End Sub
Sub Button3_Click
 HttpUtils.CallbackActivity = "Main" 'Current activity name.
 HttpUtils.CallbackJobDoneSub = "JobDone"
 HttpUtils.Download("Job1", bt3)   
End Sub

Sub Button4_Click
 HttpUtils.CallbackActivity = "Main" 'Current activity name.
 HttpUtils.CallbackJobDoneSub = "JobDone"
 HttpUtils.Download("Job1", bt4)
 End Sub
Sub Button5_Click
 HttpUtils.CallbackActivity = "Main" 'Current activity name.
 HttpUtils.CallbackJobDoneSub = "JobDone"
 HttpUtils.Download("Job1", bt5)   
End Sub

Sub Button6_Click
 HttpUtils.CallbackActivity = "Main" 'Current activity name.
 HttpUtils.CallbackJobDoneSub = "JobDone"
 HttpUtils.Download("Job1", bt6)
 End Sub
Sub Button7_Click
 HttpUtils.CallbackActivity = "Main" 'Current activity name.
 HttpUtils.CallbackJobDoneSub = "JobDone"
 HttpUtils.Download("Job1", bt7)   
End Sub

Sub Button8_Click
 HttpUtils.CallbackActivity = "Main" 'Current activity name.
 HttpUtils.CallbackJobDoneSub = "JobDone"
 HttpUtils.Download("Job1", bt8)
 End Sub
Sub Button9_Click
 HttpUtils.CallbackActivity = "Main" 'Current activity name.
 HttpUtils.CallbackJobDoneSub = "JobDone"
 HttpUtils.Download("Job1", bt9)   
End Sub
Sub Button10_Click
 HttpUtils.CallbackActivity = "Main" 'Current activity name.
 HttpUtils.CallbackJobDoneSub = "JobDone"
 HttpUtils.Download("Job1", bt10)
 End Sub
Sub Button11_Click
 HttpUtils.CallbackActivity = "Main" 'Current activity name.
 HttpUtils.CallbackJobDoneSub = "JobDone"
 HttpUtils.Download("Job1", bt11)   
End Sub
Sub ImageView1_Click
 HttpUtils.CallbackActivity = "Main" 'Current activity name.
 HttpUtils.CallbackJobDoneSub = "JobDone"
 HttpUtils.Download("Job1", bt111)   
End Sub
Sub ImageView2_Click
 HttpUtils.CallbackActivity = "Main" 'Current activity name.
 HttpUtils.CallbackJobDoneSub = "JobDone"
 HttpUtils.Download("Job1", bt112)   
End Sub
Sub ImageView3_Click
 HttpUtils.CallbackActivity = "Main" 'Current activity name.
 HttpUtils.CallbackJobDoneSub = "JobDone"
 HttpUtils.Download("Job1", bt113)   
End Sub
Sub ImageView4_Click
 HttpUtils.CallbackActivity = "Main" 'Current activity name.
 HttpUtils.CallbackJobDoneSub = "JobDone"
 HttpUtils.Download("Job1", bt114)   
End Sub
Sub ImageView5_Click
 HttpUtils.CallbackActivity = "Main" 'Current activity name.
 HttpUtils.CallbackJobDoneSub = "JobDone"
 HttpUtils.Download("Job1", bt115)   
End Sub
Sub ImageView6_Click
 HttpUtils.CallbackActivity = "Main" 'Current activity name.
 HttpUtils.CallbackJobDoneSub = "JobDone"
 HttpUtils.Download("Job1", bt116)   
End Sub
Sub ImageView7_Click
 HttpUtils.CallbackActivity = "Main" 'Current activity name.
 HttpUtils.CallbackJobDoneSub = "JobDone"
 HttpUtils.Download("Job1", bt117)   
End Sub

httpUtils
B4X:
'Version 1.04
Sub Process_Globals
   Dim Tasks As List 'List of URLs to fetch.
   'A map that holds the successful links.
   'The links are stored as keys. The values are not used.
   Dim SuccessfulUrls As Map 
   Dim Working As Boolean 'True when a job is still running
   Dim Complete As Boolean 'True after a job has completer
   Dim Job As String 'Name of the current running Job
   Dim CallbackActivity As String 'Name of Activity that handles the callbacks.
   Dim CallbackJobDoneSub As String 'Name of the JobDone callback sub.
   Dim CallbackUrlDoneSub As String 'Name of the UrlDone callback sub.
End Sub
'Download a single resource (GET method).
Sub Download(JobName As String, URL As String)
   DownloadList(JobName, Array As String(URL))
End Sub
'Downloads a list of resources (GET method).
Sub DownloadList(JobName As String, URLs As List)
   If internalCheckIfCanStart(JobName) = False Then Return
   Tasks = URLs
   HttpUtilsService.Post = False
   StartService(HttpUtilsService)
End Sub
'Sends a POST request with the given string as the post data
Sub PostString(JobName As String, URL As String, Text As String)
   PostBytes(JobName, URL, Text.GetBytes("UTF8"))
End Sub
'Sends a POST request with the given file send as the post data.
Sub PostFile(JobName As String, URL As String, Dir As String, FileName As String)
   If internalCheckIfCanStart(JobName) = False Then Return
   Dim length As Int
   If Dir = File.DirAssets Then
      Log("Cannot send files from the assets folder.")
      Return
   End If
   length = File.Size(Dir, FileName)
   Dim in As InputStream
   in = File.OpenInput(Dir, FileName)
   If length < 1000000 Then '1mb
      'There are advantages for sending the file as bytes array. It allows the Http library to resend the data
      'if it failed in the first time.
      Dim out As OutputStream
      out.InitializeToBytesArray(length)
      File.Copy2(in, Out)
      HttpUtilsService.PostInputStream = Null
      HttpUtilsService.PostBytes = out.ToBytesArray
   Else
      HttpUtilsService.PostInputStream = in
      HttpUtilsService.PostLength = length
   End If
   Tasks = Array As String(URL)
   HttpUtilsService.Post = True
   StartService(HttpUtilsService)
End Sub
'Sends a POST request with the given data as the post data.
Sub PostBytes(JobName As String, URL As String, Data() As Byte)
   If internalCheckIfCanStart(JobName) = False Then Return
   HttpUtilsService.PostInputStream = Null
   HttpUtilsService.PostBytes = Data
   Tasks = Array As String(URL)
   HttpUtilsService.Post = True
   StartService(HttpUtilsService)
End Sub
Sub internalCheckIfCanStart(JobName As String) As Boolean
   If Working Then
      Log("Already working. Request ignored (" & JobName & ")")
      Return False
   End If
   Log("Starting Job: " & JobName)
   Job = JobName
   Working = True
   Complete = False
   SuccessfulUrls.Initialize
   Return True
End Sub
Sub IsSuccess(URL As String) As Boolean
   Return SuccessfulUrls.ContainsKey(URL)
End Sub

'Get methods should be called only after the JobDone event or the UrlDone event.
Sub GetString(URL As String) As String
   If IsSuccess(URL) = False Then
      Log("Task not completed successfully.")
      Return ""
   End If
   Return File.GetText(HttpUtilsService.TempFolder, SuccessfulUrls.Get(URL))
End Sub

Sub GetBitmap(URL As String) As Bitmap
   Dim b As Bitmap
   If IsSuccess(URL) = False Then
      Log("Task not completed successfully.")
      Return b
   End If
   b = LoadBitmap(HttpUtilsService.TempFolder, SuccessfulUrls.Get(URL))
   Return b
End Sub

Sub GetInputStream(URL As String) As InputStream
   Dim in As InputStream
   If IsSuccess(URL) = False Then
      Log("Task not completed successfully.")
      Return in
   End If
   in = File.OpenInput(HttpUtilsService.TempFolder, SuccessfulUrls.Get(URL))
   Return in
End Sub

httpUtilsService
B4X:
'Version 1.04
Sub Process_Globals
   Dim Tasks As List 'List of URLs to fetch.
   'A map that holds the successful links.
   'The links are stored as keys. The values are not used.
   Dim SuccessfulUrls As Map 
   Dim Working As Boolean 'True when a job is still running
   Dim Complete As Boolean 'True after a job has completer
   Dim Job As String 'Name of the current running Job
   Dim CallbackActivity As String 'Name of Activity that handles the callbacks.
   Dim CallbackJobDoneSub As String 'Name of the JobDone callback sub.
   Dim CallbackUrlDoneSub As String 'Name of the UrlDone callback sub.
End Sub
'Download a single resource (GET method).
Sub Download(JobName As String, URL As String)
   DownloadList(JobName, Array As String(URL))
End Sub
'Downloads a list of resources (GET method).
Sub DownloadList(JobName As String, URLs As List)
   If internalCheckIfCanStart(JobName) = False Then Return
   Tasks = URLs
   HttpUtilsService.Post = False
   StartService(HttpUtilsService)
End Sub
'Sends a POST request with the given string as the post data
Sub PostString(JobName As String, URL As String, Text As String)
   PostBytes(JobName, URL, Text.GetBytes("UTF8"))
End Sub
'Sends a POST request with the given file send as the post data.
Sub PostFile(JobName As String, URL As String, Dir As String, FileName As String)
   If internalCheckIfCanStart(JobName) = False Then Return
   Dim length As Int
   If Dir = File.DirAssets Then
      Log("Cannot send files from the assets folder.")
      Return
   End If
   length = File.Size(Dir, FileName)
   Dim in As InputStream
   in = File.OpenInput(Dir, FileName)
   If length < 1000000 Then '1mb
      'There are advantages for sending the file as bytes array. It allows the Http library to resend the data
      'if it failed in the first time.
      Dim out As OutputStream
      out.InitializeToBytesArray(length)
      File.Copy2(in, Out)
      HttpUtilsService.PostInputStream = Null
      HttpUtilsService.PostBytes = out.ToBytesArray
   Else
      HttpUtilsService.PostInputStream = in
      HttpUtilsService.PostLength = length
   End If
   Tasks = Array As String(URL)
   HttpUtilsService.Post = True
   StartService(HttpUtilsService)
End Sub
'Sends a POST request with the given data as the post data.
Sub PostBytes(JobName As String, URL As String, Data() As Byte)
   If internalCheckIfCanStart(JobName) = False Then Return
   HttpUtilsService.PostInputStream = Null
   HttpUtilsService.PostBytes = Data
   Tasks = Array As String(URL)
   HttpUtilsService.Post = True
   StartService(HttpUtilsService)
End Sub
Sub internalCheckIfCanStart(JobName As String) As Boolean
   If Working Then
      Log("Already working. Request ignored (" & JobName & ")")
      Return False
   End If
   Log("Starting Job: " & JobName)
   Job = JobName
   Working = True
   Complete = False
   SuccessfulUrls.Initialize
   Return True
End Sub
Sub IsSuccess(URL As String) As Boolean
   Return SuccessfulUrls.ContainsKey(URL)
End Sub

'Get methods should be called only after the JobDone event or the UrlDone event.
Sub GetString(URL As String) As String
   If IsSuccess(URL) = False Then
      Log("Task not completed successfully.")
      Return ""
   End If
   Return File.GetText(HttpUtilsService.TempFolder, SuccessfulUrls.Get(URL))
End Sub

Sub GetBitmap(URL As String) As Bitmap
   Dim b As Bitmap
   If IsSuccess(URL) = False Then
      Log("Task not completed successfully.")
      Return b
   End If
   b = LoadBitmap(HttpUtilsService.TempFolder, SuccessfulUrls.Get(URL))
   Return b
End Sub

Sub GetInputStream(URL As String) As InputStream
   Dim in As InputStream
   If IsSuccess(URL) = False Then
      Log("Task not completed successfully.")
      Return in
   End If
   in = File.OpenInput(HttpUtilsService.TempFolder, SuccessfulUrls.Get(URL))
   Return in
End Sub
 
Upvote 0
Top