Obsługa WinRT StreamSocket rozłącza się (po stronie serwera i klienta)

Mam aplikację, którą piszę dla systemu Windows 8 / WinRT, która używa interfejsu StreamSocket API do połączenia strumieniowego z serwerem. Oznacza to, że serwer przesyła dane do klienta, czasami z metatagami, i może się rozłączyć w dowolnym momencie.

Problem, który mam, polega na tym, że nie mam pojęcia, jak wykryć, kiedy serwer się rozłączył. Wydaje się, że w klasie StreamSocket nie ma żadnych zdarzeń ani właściwości, ani jej strumieni wejściowych ani wyjściowych, ani klas DataReader / DataWriter, które mają cokolwiek wspólnego ze statusem połączenia.

Ponadto metoda DataReader ReadAsync nie zawodzi po odłączeniu się serwera od klienta. Zamiast tego operacja kończy się sukcesem, o ile wiem, a dane, które wypełnia w swoim buforze, są ostatnią rzeczą, jaką wysłał do niego serwer (tzn. Nie czyści swojego wewnętrznego bufora, chociaż widzę, że został „zużyty” bufor za każdym razem, gdy dzwonię do ReadByte). Robi to dla każdego kolejnego wywołania ReadAsync - uzupełniając bufor o to, co serwer wysłał jako ostatni przed rozłączeniem. Oto uproszczona wersja kodu:

<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);
                }
            }
        }
    }
</code>

questionAnswers(1)

yourAnswerToTheQuestion