B4J Question Server response to input from keyboard

drponciano

Member
Licensed User
Longtime User
I made a server with a UI(JavaFX) interfase. It's working OK on windws/mac but now I want to make a console/Non-UI version. I'd like to respond to commands from the keyboard as "LU" (list users), "RESET",...
I cannot find the way of using StartMessageLoop with reader.readln or something similar.
Thanks for your help.

B4X:
sub appstart(args...)
...
sys.initializestatic(...)
reader.initializa(sys.get...)
...
startmessageloop
end sub

sub readln as string
return reader.readlin
end sub

' Where or when do I put de readln to get what the user typed?
 

Quandalle

Member
Licensed User
you can do something like this
B4X:
Sub Process_Globals
    Private reader As TextReader
    Private prompt As String = "Enter a command"
End Sub

Sub AppStart (Args() As String)
    Dim sys As JavaObject
    sys.InitializeStatic("java.lang.System")
    reader.Initialize(sys.GetField("in"))
    Log (prompt)
    Do While ProcessCommand(reader.ReadLine)
        Log(CRLF & prompt)
    Loop
End Sub

Sub ProcessCommand (command As String)  As Boolean
    Select command.ToLowerCase
        Case "quit", "bye"
            Log("bye bye ")
            Return False
        Case "lu"
            Log ("the user list is ...")
        Case "reset"
            Log("reset done")
        Case "h", "help" :
            Log("valid commad are lu, reset, help, quit....")
        Case Else
            Log("invalid command : " & command)
    End Select
    Return True
End Sub
 
Upvote 0

drponciano

Member
Licensed User
Longtime User
Thanks. The problem is that, with your code, the server part stops working as there is no StartMessageLoop.
 
Upvote 0

drponciano

Member
Licensed User
Longtime User
B4X:
Sub Process_Globals
    Public server_entrada As ServerSocket
    Private cliente_entrada As Socket   

   ' To read from keybord/input
    Dim sys As JavaObject
    Dim reader As TextReader

    Private astream As AsyncStreams    
End Sub

Sub AppStart (Args() As String)
    Log("Hello world!!!")
    server_entrada.Initialize(2000, "server_entrada")
    server_entrada.Listen

    ' enable reading from input
    sys.InitializeStatic("java.lang.System")
    reader.Initialize(sys.GetField("in"))

    StartMessageLoop    ' ready to receive data from clients
End Sub

' My problem is:
' How do I do to catch input from the USER controlling the server via keyboard while using StartMessageLoop?
' --------------------------------------------------------------------------
Sub readln As String
    Return reader.ReadLine
End Sub

Sub ProcesaOrden(orden As String) As Boolean
    Select orden
        Case "END"
            'exit application, close server orderly,...
        Case "LU"
            'list clients
        Case "RESET"
            ' reset connections
        Case Else
            ' etc.
    End Select
    Return True
End Sub
'-----------------------------------------------------------------

Sub Server_entrada_NewConnection (Successful As Boolean, NewSocket As Socket)
    ' Se conecta un cliente que quiere ENVIARNOS ECG
    If Successful Then
        Log("New client")
 
        server_entrada.Close
        server_entrada.Initialize(2000,"server_entrada")
        server_entrada.Listen
        
        astream.Initialize(cliente_entrada.InputStream,cliente_entrada.OutputStream,"astream")
    End If
End Sub


Sub AStream_NewData (Buffer() As Byte)
' do things
End Sub
 
Upvote 0

Quandalle

Member
Licensed User
@drponciano

I'm not sure to understand what you want to do, but if the question is to be able to take control for reading the keyboard input while you're in MessageLoop, you have to trigger an event.
The simplest way is to arm a timer that periodically checks for the presence of an entry on the keyboard using the textreader.Ready method (non-blocking method) and if data is present will read it.
Example of code (you can test it) :

B4X:
Sub Process_Globals
    Private reader As TextReader
    Private timer1 As Timer
End Sub

Sub AppStart (Args() As String)
    Dim sys As JavaObject
    sys.InitializeStatic("java.lang.System")
    reader.Initialize(sys.GetField("in"))

    timer1.Initialize("timer1", 100 )
    timer1.Enabled = True

    StartMessageLoop
   
End Sub

Sub timer1_Tick
    If reader.Ready Then
        timer1.Enabled = False
        If ProcessCommand(reader.ReadLine) Then timer1.Enabled = True Else StopMessageLoop      
    End If
End Sub


Sub ProcessCommand (command As String)  As Boolean
    Select command.ToLowerCase
        Case "quit", "bye", "exit"
            Log("bye bye ")
            Return False
        Case "lu"
            Log ("the user list is ...")
        Case "reset"
            Log("reset done")
        Case "h", "help" :
            Log("valid commad are lu, reset, help, quit....")
        Case Else
            Log("invalid command : " & command)
    End Select
    Return True
End Sub
 
Last edited:
Upvote 0
Top