B4J Tutorial [Server] Build a printer server with PrintHtml

Discussion in 'B4J Tutorials' started by Erel, Jan 28, 2014.

  1. Erel

    Erel Administrator Staff Member Licensed User

    PrintHtml is a Windows utility that prints html files. You can see more information about it here: http://www.basic4ppc.com/android/forum/threads/print-with-printhtml-tool.35492/

    In this example we use it to print messages from the device. The device sends a POST request with the html message and the PrintServer uses jShell to call PrintHtml and print the message.

    [​IMG]

    The client code is trivial:
    Code:
    Sub Process_Globals
       
    Private link As String = "http://192.168.0.100:51042/print"
    End Sub

    Sub Activity_Create(FirstTime As Boolean)
       
    End Sub

    Sub Activity_Click
       
    Dim j As HttpJob
       j.Initialize(
    "j", Me)
       j.PostString(link, 
    "This is a test message sent from the device...")
    End Sub

    Sub JobDone(j As HttpJob)
       
    If j.Success Then
         
    Log("Success: " & j.GetString)
       
    Else
         
    Log("Error: " & j.ErrorMessage)
       
    End If
       j.Release
    End Sub
    The server code is more interesting. We want the server to handle requests one after another. There are no advantages for sending multiple printer jobs and it is also not clear whether PrintHtml and the printer driver support concurrent jobs.
    This is done by setting the SingleThreaded parameter to True:
    Code:
    Sub Process_Globals
       
    Private srvr As Server
    End Sub

    Sub AppStart (Args() As String)
       srvr.Initialize(
    "")
       srvr.Port = 
    51042
       srvr.AddHandler(
    "/print""Print"True'SingleThreaded = True
       srvr.Start
       StartMessageLoop
    End Sub
    jShell library runs the task in the background and raises the ProcessCompleted event when the task completes. This means that we need to pause the current request until the task completes and then resume it. Otherwise the Handle sub will be completed before the task completes. The response is committed when the execution of Handle completes.

    This is done by calling StartMessageLoop in the Handle sub and then StopMessageLoop in js_ProcessCompleted sub:

    Code:
    Sub Class_Globals
       
    Private js As Shell
       
    Private mresp As ServletResponse
    End Sub

    Public Sub Initialize

    End Sub

    Sub Handle(req As ServletRequest, resp As ServletResponse)
       mresp = resp
       
    'save the request to a file
       Dim out As OutputStream = File.OpenOutput(File.DirApp, "temp.txt"False)
       
    File.Copy2(req.InputStream, out)
       out.Close
       
    Dim params As List
       params.Initialize
       
    'optionally set the printer
       'params.Add("printername=novapdf")
       params.Add("file=temp.txt")
       js.Initialize(
    "js""printhtml.exe", params)
       js.WorkingDirectory = 
    File.DirApp
       js.Run(-
    1)
       StartMessageLoop 
    '<--- wait for the event
    End Sub

    Sub js_ProcessCompleted (Success As Boolean, ExitCode As Int, StdOut As String, StdErr As String)
       
    Log("Success=" & Success & ", StdOut=" & StdOut & ", StdErr=" & StdErr)
       
    If Success Then
         mresp.Write(
    "Message was printed successfully.")
       
    Else
         mresp.SendError(
    500, StdErr)
       
    End If
       StopMessageLoop 
    '<-- close the secondary message loop
    End Sub
     
    BPak, lemonisdead and maXim like this.
  2. giga

    giga Well-Known Member Licensed User

    Erel, Are you some sort of code machine or something? You come up with new ideas everyday. :) BIG THANKS.
     
  3. Erel

    Erel Administrator Staff Member Licensed User

    :)

    I actually have many more ideas and possible development directions. However sometimes I feel that I may be running too fast... I always prefer to be close to the developers who will actually use it and then continue the development based on the feedback.
     
  4. FranckB

    FranckB Member Licensed User

    Hi all,

    Witch librairies may i include to run this print server ?
    I would like to have a nonUI service running in background what i can call with any browser like "http://localhost:51042/print?12345" to print the "12345.txt" file.
    I have this error when running :

    B4J version: 4.50
    Parsing code. (0.00s)
    Compiling code. Error
    Error compiling program.
    Error description: La référence d'objet n'est pas définie à une instance d'un objet.
    Occurred on line: 7
    srvr.Port = 51042
    Word: port

    Thank's by advance.
    Franck

    UPDATE : Sorry to have disturb you, it works !!! Thanks
     
    Last edited: Jun 7, 2018
  5. Erel

    Erel Administrator Staff Member Licensed User

    Why are you using B4J v4.50???

    You should upgrade to v6.30.
     
    Beja likes this.
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