Subject: Adverse internet connection conditions
In an application that is supposed to properly work under lossy and slow internet connections (e.g. mobile EDGE, 3G), following issues arise:
1. If it is critical to be sure that the stream is healthy, the StreamActive property of XmppClient is not of much help. E.g., if user turns on the "Airplane mode", StreamActive is still true in spite of client's inability to send or retrieve anything from the server. This particular problem may be mitigated with WinRT's NetworkInformation.GetInternetConnectionProfile(); but in general, it seems like there are no reliable routines to check health of the stream in Matrix.
2. Hence, an app needs to manually watch for DateTime of last received stanza, perform pings from time to time, etc.. However, when the app is through some other means is sure that the connectivity is lost, it is not always easy to re-establish it. When connection is absent, a call to XmppClient.Close() will not result in an instant abortion of the stream. The OnClosed event may be fired about 10-15 seconds after a call to Close. Furthermore, a call to Open before OnClosed often results in unpredictable behavior, leading sometimes to complete inability of an XmppClient to re-establish the connection. It would be helpful to have an additional Abort method, that would instantly (or nearly-so) close the connection, clean-up XmppClient's inner state and allow for its re-establishment.
3. Suppose a connection check is required before sending particular stanza. To achieve this, app sends a ping and expects a pong. However, when the connection is busy with downloading data, e.g. when the server writes a heavy IQ result to the stream, a pong stanza may not come in minutes. It would be helpful to have a DateTime of last received chunk of bytes from the server, so that the app could knew that the stream is active and healthy.
Ideally, something like a following API would be rather helpful:
There, IsConnectedAsync would ideally perform a ping if there were no bytes received from the server in a given time period (configurable).
I've implemented something like this at the app level; however, due to Matrix's hiding of the inner socket workings, this solution has many downsides and may not be entirely reliable. Workarounds with an Abort method and a DateTime property showing when some bytes were received from the server last time would be appreciated.
1. If it is critical to be sure that the stream is healthy, the StreamActive property of XmppClient is not of much help. E.g., if user turns on the "Airplane mode", StreamActive is still true in spite of client's inability to send or retrieve anything from the server. This particular problem may be mitigated with WinRT's NetworkInformation.GetInternetConnectionProfile(); but in general, it seems like there are no reliable routines to check health of the stream in Matrix.
2. Hence, an app needs to manually watch for DateTime of last received stanza, perform pings from time to time, etc.. However, when the app is through some other means is sure that the connectivity is lost, it is not always easy to re-establish it. When connection is absent, a call to XmppClient.Close() will not result in an instant abortion of the stream. The OnClosed event may be fired about 10-15 seconds after a call to Close. Furthermore, a call to Open before OnClosed often results in unpredictable behavior, leading sometimes to complete inability of an XmppClient to re-establish the connection. It would be helpful to have an additional Abort method, that would instantly (or nearly-so) close the connection, clean-up XmppClient's inner state and allow for its re-establishment.
3. Suppose a connection check is required before sending particular stanza. To achieve this, app sends a ping and expects a pong. However, when the connection is busy with downloading data, e.g. when the server writes a heavy IQ result to the stream, a pong stanza may not come in minutes. It would be helpful to have a DateTime of last received chunk of bytes from the server, so that the app could knew that the stream is active and healthy.
Ideally, something like a following API would be rather helpful:
await xmppClient.OpenAsync(); // await finishes when first bytes are received from the server
bool isConnected = await xmppClient.IsConnectedAsync(); // returns true if XmppClient is sure that the stream is healthy
bool isConnected = await xmppClient.IsConnectedAsync(); // returns true if XmppClient is sure that the stream is healthy
There, IsConnectedAsync would ideally perform a ping if there were no bytes received from the server in a given time period (configurable).
I've implemented something like this at the app level; however, due to Matrix's hiding of the inner socket workings, this solution has many downsides and may not be entirely reliable. Workarounds with an Abort method and a DateTime property showing when some bytes were received from the server last time would be appreciated.