B4A Library [class] AsyncStreamsText - Useful when working with streams of text

Discussion in 'Additional libraries, classes and official updates' started by Erel, Mar 5, 2013.

  1. Erel

    Erel Administrator Staff Member Licensed User

    When a message (set of bytes) is sent over a network channel, of any type, there is no guarantee that the whole message will arrive as a single set of bytes.

    The message might be split or merged together with other messages.

    One way to overcome this issue is to initialize AsyncStreams in "prefix" mode. In this mode a 4 bytes header is added to each message with the message length. This allows AsyncStreams to internally build the messages correctly. However you can only use prefix mode if both sides of the connection adhere to this protocol. If for example you connect to a Bluetooth GPS then you cannot use prefix mode.

    AsyncStreamsText can help you if:
    1. The data sent is text and not binary data.
    2. Each message ends with an end of line character (both Unix and Windows formats will work).

    AsyncStreamsText works by handling the NewData event and looking for the end of line characters.

    Using AsyncStreamsText is simple:
    Code:
    Sub Process_Globals
       
    Private ast As AsyncStreamsText
       
    Private server As ServerSocket
    End Sub

    Sub Globals
    End Sub

    Sub Activity_Create(FirstTime As Boolean)
       
    If FirstTime Then
          
    server.Initialize(5555"server")
          
    Log(server.GetMyWifiIP)
          
    server.Listen
       
    End If
    End Sub

    Sub server_NewConnection (Successful As Boolean, NewSocket As Socket)
       
    If Successful Then
          
    If ast.IsInitialized Then ast.Close
          ast.Initialize(Me, 
    "ast", NewSocket.InputStream, NewSocket.OutputStream) 'initialize AsyncStreamsText with the socket streams.
       Else
          
    Log(LastException)
       
    End If
       
    server.Listen
    End Sub

    Sub ast_NewText(Text As String)
       
    Log("Text: " & Text)
       
    Log(Text.Length)
    End Sub

    Sub ast_Terminated
       
    Log("Connection terminated")
    End Sub

    Sub Activity_Click
       ast.Write(
    "this is an example..." & Chr(10) & Chr(13))
    End Sub
    NewText event is raised each time that there is a complete message available.

    Note that AsyncStreamsText.Write writes text and not bytes.
    The charset field sets the encoding used to convert the bytes to string and vice versa.
     

    Attached Files:

    Last edited: Apr 3, 2014
  2. positrom2

    positrom2 Active Member Licensed User

    Is there some advantage of the AsyncStreamsText example compared to using textreader since in both variants only text can be transmitted?

    When I compile or invoke the libraries (network and random access) the windows firewall is asking if java shall be blocked or not. I am curious on the reason for internet access when it seems not to be needed...
    Regards, positrom2
     
  3. Erel

    Erel Administrator Staff Member Licensed User

    You cannot use TextReader with network streams. This will block the main thread.

    This is not related to these libraries. This is probably Java which tries to check for updates.
     
  4. positrom2

    positrom2 Active Member Licensed User

    Hi Erel,
    thanks for the answers.
    I am using textreader in BT and WiFi connections. What happens, is that the code will wait "forever" until text (data numbers) are coming in terminated by CR&LF (or one of those, not sure). Although that is waisting CPU time, it assures that I know that I am subsequently processing the actual data. Consider trying to synchronize the steps of a stepper motor with data read in corresponding to the actual position of the motor. Would that be possible with asyncstreams? If data were fetched as they come in and the data processing would run independently I suspect that synchronization is less than straightforward to achieve.

    As you see, I am following the asyncstream posts since I would like to receive the data in binary format (I had some posts here on this issue earlier). So the questions are if my assumptions mentioned here are right - and if not how - how your example could be modified to receive a binary data stream.
    Regards, positrom2
     
  5. Erel

    Erel Administrator Staff Member Licensed User

    I should have written: you should not use TextReader with network streams. Also note that on Android 4+ (when targetSdkVersion > 11) you will get an exception in that case.

    AsyncStreams objects handles binary data. You do not need to do anything special. I think that it is better if you start a new thread and give more details about the problem you are trying to solve.
     
    lemonisdead likes this.
  6. ADPTraining

    ADPTraining Member Licensed User

    Erel, I'm getting an error ast not initialized. Any help appreciated...
     
    xeriko likes this.
  7. Erel

    Erel Administrator Staff Member Licensed User

    Are you initializing the object? Can you post your code and the full error message from the logs?
     
  8. dddvvv

    dddvvv Member Licensed User

    Erel, how would I have to start, to mod this class for bluetooth text comms?

    Thanks
     
  9. Stulish

    Stulish Active Member Licensed User

    Also,

    Could this be used with USBSerial Comms??

    Thanks

    Stu
     
  10. agraham

    agraham Expert Licensed User

    It should do as it sits on top of AsyncStreams and doesn't know about anything underneath. Why not just try it?
     
  11. RichardBernard

    RichardBernard Member Licensed User

    Thank You!

    Erel,

    Just wanted to thank you for this class buddy! It came handy!!


    R
     
  12. PhilN

    PhilN Member Licensed User

    Hi Errol, thanks for the AsyncStreamsText Class. When I run the app (your example code), I am getting an error:
    asyncstreamstext_write (java line: 140)
    java.io.UnsupportedEncodingException:

    Not sure how to fix it. :sign0163:
     
  13. PhilN

    PhilN Member Licensed User

    Don't worry. I managed to fix the problem... Thanks anyway!
     
  14. Erel

    Erel Administrator Staff Member Licensed User

    In your project choose Project - Add Existing Module.
     
    merlin2049er and slydog43 like this.
  15. merlin2049er

    merlin2049er Well-Known Member Licensed User

    What happens when you load a module? Does it show up somewhere that it's loaded?

    Ok, on a new tab. Neat.
     
    Last edited: Aug 26, 2013
  16. Erel

    Erel Administrator Staff Member Licensed User

    This is not a library. It is a class which you should add to your project. If you like you can compile it into a library.

    The projects related to AsyncStreams are listed in the tutorial: AsyncStreams Tutorial
     
  17. synasir

    synasir Member Licensed User

    Great work as always, Erel.
     
  18. Tom Christman

    Tom Christman Active Member Licensed User

    I'm trying the code listing in the first post (by Erel) substituting a Usb connection for server connection, and the "Private ast As AsyncSteamsText" line in Process Globals is not accepted (red) in B4A. I also downloaded the attached AstreamsText.bas which is a "class" which doesn't appear to be connected to the presented code. What am I doing wrong, as I'm trying to use the posted code to receive text from a ucomputer via a usb connection. The usb connection funtions with the AsyncStreams code, but I have a problem with errors in byte reception, and the data is text anyway.
     
  19. Erel

    Erel Administrator Staff Member Licensed User

    Have you added the module to your project (Project - Add Existing Module)?
     
  20. Tom Christman

    Tom Christman Active Member Licensed User

    Erel Thanks for the speedy reply and
    Yes I added the module.
    I then replaced

    Code:
    Sub Process_Globals
    Private ast As AsyncSteamsText
    Private server As ServerSocket
    End Sub
    with

    Code:
    Sub Process_Globals
    Dim ast As AsyncStreamsText
    Dim usb As UsbSerial
    End Sub
    Then I substituted the posted code section

    Code:
    Sub Activity_Create(FirstTime AsBoolean)
    If FirstTime Then
    server.Initialize(5555"server")Log(server.GetMyWifiIP)
    server.Listen
    EndIf
    End Sub
    Sub server_NewConnection (Successful As Boolean, NewSocket As Socket)
      
    If Successful Then
          
    If ast.IsInitialized Then ast.Close
          ast.Initialize(Me, 
    "ast", NewSocket.InputStream, NewSocket.OutputStream) 'initialize AsyncStreamsText with the socket streams.
      Else
          
    Log(LastException)
      
    End If
      
    server.Listen
    End Sub
    With this code

    Code:
    Sub Activity_Create(FirstTime As Boolean)
       
    Activity.LoadLayout("1")
       btnClose.Enabled = 
    False
       btnSend.Enabled = 
    False
    End Sub

    Sub btnOpen_Click
       
    If usb.UsbPresent = usb.USB_NONE Then
         
    Log("Msgbox - no device")
         
    Msgbox("No USB device or accessory detected!""Error")
         
    Log("Msgbox - returned")
         
    Return
       
    End If
      
       
    Log("Checking permission")
       
    If (usb.HasPermission) Then
         
    'Msgbox(usb.DeviceInfo, "Device Information")
         usb.SetParameters(9600,8,1,0)
         usb.UsbTimeout = 
    1000
        
         
    Dim dev As Int
         dev = usb.Open(
    9600)
         
    'usb.UsbTimeout=100
        
         
    If dev <> usb.USB_NONE Then
           
    Log("Connected successfully!")
           btnOpen.Enabled = 
    False
           btnClose.Enabled = 
    True
           btnSend.Enabled = 
    True
          ast.Initialize(usb.GetInputStream, usb.GetOutputStream, 
    "ast")
          
         
    Else
           
    Log("Error opening USB port")
         
    End If
       
    Else
         usb.RequestPermission
       
    End If
      
    End Sub
    And the code
    Code:
    ast.Initialize(usb.GetInputStream, usb.GetOutputStream, "ast")
    gives a compiler error.
     
    Last edited: Dec 7, 2013
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