Der Englische Originaltext.
Ein neuer Objekt-Type, AsyncStreams, befindet sich in der RandomAccessFile Library.
AsyncStreams ermöglicht, Daten aus einem InputStream zu lesen und Daten in einen OutputStream zu schreiben ohne das Programm zu blockieren. Das Lesen und Schreiben wird in zwei separaten Threads vorgenommen.
Wenn neue Daten verfügbar sind, wird das NewData Event ausgelöst und enthält die Daten.
Wenn man Daten in einen OutputStream schreibt, werden diese in einer internen Warteschlange aufgenommen und dann in den Hintergrund geschickt.
AsyncStreams ist sehr nützlich wenn man mit langsamen Streams wie Netzwerk-Streams oder Bluetooth-Streams arbeitet.
Wenn man mit solchen Streams im Haupt-Thread arbeitet, kann das Programm, während dem Warten auf einen Wert, hängen bleiben oder blockieren.
Wir hatten im Serial Tutorial und im Network Tutorial versucht mit einem Timer zu arbeiten der überprüft ob Bytes im Puffer zur Verfügung stehen. Doch selbst wenn Bytes verfügbar sind, gibt es ein Risiko daß nicht genügend vorhanden sind und dann unser Programm hängen bleibt oder blockiert bis diese verfügbar sind.
AsyncStreams ist in der Regel einfacher und sicherer.
AsyncStreams kann in zwei Modi arbeiten. Regelmäßiger Modus und "Präfix-Modus". Beide arbeiten wie oben beschrieben.
Der folgende Code demonstriert ein einfaches Programm, das Text an ein angeschlossenes Gerät oder einen angeschlossenen Computer sendet:
Sobald eine Verbindung da ist initilisieren wir das AsyncStreams Objekt:
Dann, wenn neue Daten bereit sind, konvertieren wir diese ihn in einen String und zeigen ihn an:
Wenn der Benutzer Text in die EditText eingibt, wird der Texte abgesandt:
Prefix Modus
Wenn das Objekt im Prefix Modus initialisiert ist, müssen die Daten folgendes Protokoll einhalten: jede Nachricht (Byte-Array) muß mit der Länge des Byte-Arrays (als Int) beginnen. Das heißt daß, wenn ein anderes Gerät eine Nachricht von 100 Bytes sendet, beginnt der Stream mit 4 Bytes mit einem Wert von 100 und dann folgen die 100 Bytes.
Das NewData Event wird ausgelöst und enthält die 100 Bytes. Die 4 Präfix-Bytes sind im Event nicht enthalten.
Wenn man Daten mit Write oder Write2 sendet wird die Arraylänge automatisch als Präfix der Nachricht voran gesetzt.
Es ist dringend empfohlen im Präfix-Modus zu arbeiten, was aber nur möglich ist wenn man ihn auf beiden Seiten implementiert. AsyncStreams nutzt die Länge des Byte-Arrays aus, um sicherzustellen, daß das NewData Event nur mit vollständigen Meldungen ausgelöst wird. Wenn zum Beispiel 100 Bytes erwartet werden aber nur 60 Bytes angekommen sind, wird es warten, bis die restlichen 40 Bytes ankommen sind. Im normalen Modus wird das Event zweimal ausgelöst, und man muß die beiden Teile der Nachricht separat behandeln.
AsyncStreams behandelt auch den Fall wenn 100 Bytes erwartet werden und mehr als 100 Bytes angekommen sind (was heißt daß es mehrere Nachrichten gibt).
Ein Error Event wird ausgelöst falls es irgendeinen Fehler gibt. Man kann LastException benutzen um den Grund des Fehlers zu finden.
Ein neuer Objekt-Type, AsyncStreams, befindet sich in der RandomAccessFile Library.
AsyncStreams ermöglicht, Daten aus einem InputStream zu lesen und Daten in einen OutputStream zu schreiben ohne das Programm zu blockieren. Das Lesen und Schreiben wird in zwei separaten Threads vorgenommen.
Wenn neue Daten verfügbar sind, wird das NewData Event ausgelöst und enthält die Daten.
Wenn man Daten in einen OutputStream schreibt, werden diese in einer internen Warteschlange aufgenommen und dann in den Hintergrund geschickt.
AsyncStreams ist sehr nützlich wenn man mit langsamen Streams wie Netzwerk-Streams oder Bluetooth-Streams arbeitet.
Wenn man mit solchen Streams im Haupt-Thread arbeitet, kann das Programm, während dem Warten auf einen Wert, hängen bleiben oder blockieren.
Wir hatten im Serial Tutorial und im Network Tutorial versucht mit einem Timer zu arbeiten der überprüft ob Bytes im Puffer zur Verfügung stehen. Doch selbst wenn Bytes verfügbar sind, gibt es ein Risiko daß nicht genügend vorhanden sind und dann unser Programm hängen bleibt oder blockiert bis diese verfügbar sind.
AsyncStreams ist in der Regel einfacher und sicherer.
AsyncStreams kann in zwei Modi arbeiten. Regelmäßiger Modus und "Präfix-Modus". Beide arbeiten wie oben beschrieben.
Der folgende Code demonstriert ein einfaches Programm, das Text an ein angeschlossenes Gerät oder einen angeschlossenen Computer sendet:
B4X:
Sub Process_Globals
Dim AStreams As AsyncStreams
Dim Server As ServerSocket
Dim Socket1 As Socket
End Sub
Sub Globals
Dim EditText1 As EditText
End Sub
Sub Activity_Create(FirstTime As Boolean)
If FirstTime Then
Server.Initialize(5500, "Server")
Server.Listen
Log("MyIp = " & Server.GetMyIP)
End If
EditText1.Initialize("EditText1")
EditText1.ForceDoneButton = True
Activity.AddView(EditText1, 10dip, 10dip, 300dip, 60dip)
End Sub
Sub Server_NewConnection (Successful As Boolean, NewSocket As Socket)
If Successful Then
ToastMessageShow("Connected", False)
Socket1 = NewSocket
AStreams.InitializePrefix(Socket1.InputStream, False, Socket1.OutputStream, "AStreams")
Else
ToastMessageShow(LastException.Message, True)
End If
Server.Listen
End Sub
Sub AStreams_NewData (Buffer() As Byte)
Dim msg As String
msg = BytesToString(Buffer, 0, Buffer.Length, "UTF8")
ToastMessageShow(msg, False)
Log(msg)
End Sub
Sub AStreams_Error
ToastMessageShow(LastException.Message, True)
End Sub
'press on the Done button to send text
Sub EditText1_EnterPressed
If AStreams.IsInitialized = False Then Return
If EditText1.Text.Length > 0 Then
Dim buffer() As Byte
buffer = EditText1.Text.GetBytes("UTF8")
AStreams.Write(buffer)
EditText1.SelectAll
Log("Sending: " & EditText1.Text)
End If
End Sub
Sub Activity_Pause(UserClosed As Boolean)
If UserClosed Then
Log("closing")
AStreams.Close
Socket1.Close
End If
End Sub
B4X:
AStreams.InitializePrefix(Socket1.InputStream, False, Socket1.OutputStream, "AStreams")
B4X:
Sub AStreams_NewData (Buffer() As Byte)
Dim msg As String
msg = BytesToString(Buffer, 0, Buffer.Length, "UTF8")
ToastMessageShow(msg, False)
End Sub
B4X:
Sub EditText1_EnterPressed
If AStreams.IsInitialized = False Then Return
If EditText1.Text.Length > 0 Then
Dim buffer() As Byte
buffer = EditText1.Text.GetBytes("UTF8")
AStreams.Write(buffer)
EditText1.SelectAll
Log("Sending: " & EditText1.Text)
End If
End Sub
Wenn das Objekt im Prefix Modus initialisiert ist, müssen die Daten folgendes Protokoll einhalten: jede Nachricht (Byte-Array) muß mit der Länge des Byte-Arrays (als Int) beginnen. Das heißt daß, wenn ein anderes Gerät eine Nachricht von 100 Bytes sendet, beginnt der Stream mit 4 Bytes mit einem Wert von 100 und dann folgen die 100 Bytes.
Das NewData Event wird ausgelöst und enthält die 100 Bytes. Die 4 Präfix-Bytes sind im Event nicht enthalten.
Wenn man Daten mit Write oder Write2 sendet wird die Arraylänge automatisch als Präfix der Nachricht voran gesetzt.
Es ist dringend empfohlen im Präfix-Modus zu arbeiten, was aber nur möglich ist wenn man ihn auf beiden Seiten implementiert. AsyncStreams nutzt die Länge des Byte-Arrays aus, um sicherzustellen, daß das NewData Event nur mit vollständigen Meldungen ausgelöst wird. Wenn zum Beispiel 100 Bytes erwartet werden aber nur 60 Bytes angekommen sind, wird es warten, bis die restlichen 40 Bytes ankommen sind. Im normalen Modus wird das Event zweimal ausgelöst, und man muß die beiden Teile der Nachricht separat behandeln.
AsyncStreams behandelt auch den Fall wenn 100 Bytes erwartet werden und mehr als 100 Bytes angekommen sind (was heißt daß es mehrere Nachrichten gibt).
Ein Error Event wird ausgelöst falls es irgendeinen Fehler gibt. Man kann LastException benutzen um den Grund des Fehlers zu finden.