I have an application I'm writing for Windows 8/WinRT that uses the StreamSocket API to do a streaming connection to a server. That is to say, the server streams data to the client, sometimes with meta tags, and can disconnect at any time.
The problem I'm having is that I have no idea how to detect when the server has disconnected. There don't appear to be any events or properties on the StreamSocket class, either its input or output streams, or on the DataReader/DataWriter classes that have anything to do with connection status.
On top of that, the DataReader method ReadAsync is not failing after the server side disconnects from the client. Instead, the operation succeeds as far as I can tell, and the data it fills into its buffer is just the last thing the server sent to it (i.e. it's not clearing its internal buffer, even though I can see that it has "consumed" the buffer each time I call ReadByte). It does this for every subsequent call to ReadAsync - refilling the buffer with what the server sent last before it disconnected. Here is a simplified version of the code:
public async Task TestSocketConnectionAsync()
{
var socket = new StreamSocket();
await socket.ConnectAsync(new HostName(Host), Port.ToString(),
SocketProtectionLevel.PlainSocket);
var dr = new DataReader(socket.InputStream);
dr.InputStreamOptions = InputStreamOptions.Partial;
this.cts = new CancellationTokenSource();
this.listenerOperation = StartListeningAsync(dr, cts);
}
public async Task StartListeningAsync(DataReader dr, CancellationTokenSource cts)
{
var token = cts.Token;
while (true)
{
token.ThrowIfCancellationRequested();
var readOperation = dr.LoadAsync(1024);
var result = await readOperation;
if (result <= 0 || readOperation.Status != Windows.Foundation.AsyncStatus.Completed)
{
cts.Cancel(); // never gets called, status is always Completed, result always > 0
}
else
{
while (dr.UnconsumedBufferLength > 0)
{
byte nextByte = dr.ReadByte();
// DriveStateMachine(nextByte);
}
}
}
}