Android Question What causes AsyncStreams "Connection Terminated"?

GuyBooth

Active Member
Licensed User
I am running AsyncStreamsText classes on an internal network (TCP/IP) and I would say that all of my communications end with the "_Terminated" event being called when the remote device is sending or has just finished sending to the tablet on which the app is running. Sometimes the message looks as though it has been prematurely ended (though interestingly enough always at the same place in the stream of data). Other times it looks as though the message has in fact been completely sent.

One instance is attached to a ServerSocket, the others are attached to "standard" sockets.
The AsyncStreamsText tutorial says this event is raised when the Connection is "unexpectedly" terminated.

What actually will cause the termination? Is there a timeout? If so is there a way to extend it?
Thanks.
 

GuyBooth

Active Member
Licensed User
Thanks for the info Erel.
I assume trying to use this event would not give me a chance to send an acknowledgement (200 OK) message because the AsyncStream is closed at that point.

If I modify the class to add a "DataComplete" event into the _NewData like this:

B4X:
Private Sub astreams_NewData (Buffer() As Byte)
    Dim newDataStart As Int = sb.Length
    sb.Append(BytesToString(Buffer, 0, Buffer.Length, charset))
    Dim s As String = sb.ToString
    Dim start As Int = 0
    For i = newDataStart To s.Length - 1
        Dim c As Char = s.CharAt(i)
            If i = 0 AND c = Chr(10) Then '\n...
            start = 1 'might be a broken end of line character
            Continue
        End If
        If c = Chr(10) Then '\n
            CallSubDelayed2(mTarget, mEventName & "_NewText", s.SubString2(start, i))
            start = i + 1
        Else If c = Chr(13) Then '\r
            CallSubDelayed2(mTarget, mEventName & "_NewText", s.SubString2(start, i))
            If i < s.Length - 1 AND s.CharAt(i + 1) = Chr(10) Then '\r\n
                i = i + 1
            End If
            start = i + 1
        End If
    Next
    If start > 0 Then sb.Remove(0, start)

   ' When the buffer is empty trigger a DataComplete Event
    If SubExists(mTarget, mEventName & "_DataComplete") Then
        CallSubDelayed(mTarget, mEventName & "_DataComplete")
    End If

End Sub
I can trigger an acknowledge message from the calling program:
B4X:
' Called from the AsyncStreams class when the buffer is empty
Sub astEvents_DataComplete
    ' Send 200 ok etc
    astEvents.Write(sAcknowledge)
    TMM.DBLog("astEvents Acknowledged " & sAcknowledge)
End Sub
Does this make sense?
 

GuyBooth

Active Member
Licensed User
I understand. But a NewText event only tells me that the end of the line has been reached, not the end of the package. In my case I see a Newtext for each "line" in the response arriving at my tablet, and there are several lines. I should respond with a "200 OK" to the last one received before the AsyncStream terminates.

Or do I?
If I wait until the Astreams_Terminated event, can I still respond using write(Text) even though the other side has closed the connection?
 

GuyBooth

Active Member
Licensed User
No. You cannot send anything after this event.
Thanks for the info Erel.
In all but one situation I can use the last line, which is the ONLY blank line in the response, as a trigger, and that seems to be working.
The other situation involves responses that look incomplete, which may be poor handling from the source. As it happens, the spec for this part of the protocol says I should respond with "200 OK", not must. So theoretically I can get away without sending an acknowledgement. Not clean, but workable.
 
Top