B4J Code Snippet Resumable Subs (wait for / sleep) in server handlers

Discussion in 'B4J Code Snippets' started by Erel, Jul 19, 2017.

  1. Erel

    Erel Administrator Staff Member Licensed User

    Resumable subs can only work when there is a message queue.

    By default, server handlers end when the Handle sub is completed. They do not create a message loop.
    If you want to wait for an event then you need to call StartMessageLoop and later StopMessageLoop.

    Example of handler that downloads a page and returns it as the response:
    Code:
    Sub Handle(req As ServletRequest, resp As ServletResponse)
       Download(resp)
       StartMessageLoop 
    '<---
    End Sub

    Sub Download (resp As ServletResponse)
       
    Dim j As HttpJob
       j.Initialize(
    "", Me)
       j.Download(
    "https://www.example.com")
       
    Wait For (j) JobDone(j As HttpJob)
       
    If j.Success Then
         resp.Write(j.GetString)
       
    End If
       j.Release
       StopMessageLoop 
    '<----
    End Sub
    The Handle sub cannot be a resumable sub itself.

    Why?

    - Wait For / Sleep must be called before the call to StartMessageLoop or they will never be executed.
    - Wait For / Sleep code flow is equivalent to Return so if they appear before StartMessageLoop then the message loop will never be created and the handler will complete before the event is raised.

    WebSocket handlers do have a message loop so nothing special should be done there.

    Tip: Use the correct library.
    OkHttpUtils2_NonUI for server apps and OkHttpUtils2 for UI apps.
     
    Last edited: Jul 19, 2017
  2. jinyistudio

    jinyistudio Active Member Licensed User

    Hi

    Do i need to implement JobDone in your example like following red block?

    Code:
    Sub Handle(req AsServletRequest, resp AsServletResponse)
       Download(resp)
       StartMessageLoop 
    '<---
    End Sub

    Sub Download (resp AsServletResponse)Dim j AsHttpJob
       j.Initialize(
    "", Me)
       j.Download(
    "https://www.example.com")WaitFor (j) JobDone(j AsHttpJob)If j.Success Then
       resp.Write(j.GetString)EndIf
       j.Release
       StopMessageLoop 
    '<----
    End Sub


    Sub JobDone(j AsHttpJob)
       
    if j.success then
          ...
       
    end if
    End sub
     
    Last edited: Jul 26, 2017
  3. Erel

    Erel Administrator Staff Member Licensed User

    Please use [code]code here...[/code] tags when posting code.
     
  4. derez

    derez Expert Licensed User

    I tried sleep in a handle sub, it works in debug mode, doesn't work in release.
    Caused me some head-banging till I remembered this thread...
     
  5. derez

    derez Expert Licensed User

    Solved, I found that I need to use the service httpUtils2Service and httpjob class instead of the libraries.

    With the example from the first post, modified slightly, I have
    Code:
    Sub Class_Globals
        
    Private st As String
    End Sub

    Public Sub Initialize
     
    End Sub
    Sub Handle(req As ServletRequest, resp As ServletResponse)
        st = req.GetParameter(
    "action")
        Download( resp)
        StartMessageLoop 
    '<---
    End Sub

    Sub Download (resp As ServletResponse)
        
    Dim j As HttpJob
        j.Initialize(
    "", Me)
     
        
    If st = "on" Then
            j.Download(
    "http://192.168.0.190/cgi-bin/relay.cgi?on")  ' error is from here
        Else
            j.Download(
    "http://192.168.0.190/cgi-bin/relay.cgi?off")
        
    End If
        
    Wait For (j) JobDone(j As HttpJob)
        
    If j.Success Then
            resp.Write(st)
        
    End If
        j.Release
        StopMessageLoop 
    '<----
    End Sub
    When run I get this error:
    The httpjob works correctly on the target when run from a UI b4j app :
    Code:
    Dim j As HttpJob
    j.Initialize(
    "sendon",Me)
    j.Download(
    "http://192.168.0.190/cgi-bin/relay.cgi?on")
    Help ?
     
    Last edited: Nov 2, 2017
  6. Erel

    Erel Administrator Staff Member Licensed User

    It is not really related to this thread, however you need to use jOkHttpUtils2_NONUI in non-ui projects.
     
  7. derez

    derez Expert Licensed User

    OK(httpUtils2_NONUI), thanks
     
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice