{"record":{"id":"4a351d9e5e9c3db3","repo":"mgth/LittleBigMouse","slug":"vidaa-closed-the-mqtt-connection","errorCode":null,"errorMessage":"VIDAA closed the MQTT connection.","messagePattern":"VIDAA closed the MQTT connection\\.","errorType":"exception","errorClass":"EndOfStreamException","httpStatus":null,"severity":"error","filePath":"LittleBigMouse.Plugins/LittleBigMouse.Plugin.Vcp.Avalonia/HisenseVidaa/VidaaMqttConnection.cs","lineNumber":260,"sourceCode":"        do\n        {\n            encoded = await ReadByteAsync(stream, cancellationToken).ConfigureAwait(false);\n            length += (encoded & 127) * multiplier;\n            multiplier *= 128;\n            if (multiplier > 128 * 128 * 128 * 128)\n                throw new IOException(\"Malformed MQTT remaining length.\");\n        } while ((encoded & 128) != 0);\n\n        var payload = new byte[length];\n        await stream.ReadExactlyAsync(payload, cancellationToken).ConfigureAwait(false);\n        return (header, payload);\n    }\n\n    static async Task<byte> ReadByteAsync(Stream stream, CancellationToken cancellationToken)\n    {\n        var buffer = new byte[1];\n        if (await stream.ReadAsync(buffer, cancellationToken).ConfigureAwait(false) != 1)\n            throw new EndOfStreamException(\"VIDAA closed the MQTT connection.\");\n        return buffer[0];\n    }\n\n    static void WriteUtf8(Stream stream, string value)\n    {\n        var bytes = Encoding.UTF8.GetBytes(value);\n        if (bytes.Length > ushort.MaxValue) throw new ArgumentOutOfRangeException(nameof(value));\n        WriteUInt16(stream, (ushort)bytes.Length);\n        stream.Write(bytes);\n    }\n\n    static void WriteUInt16(Stream stream, ushort value)\n    {\n        Span<byte> bytes = stackalloc byte[2];\n        BinaryPrimitives.WriteUInt16BigEndian(bytes, value);\n        stream.Write(bytes);\n    }\n","sourceCodeStart":242,"sourceCodeEnd":278,"githubUrl":"https://github.com/mgth/LittleBigMouse/blob/7a42f01d47d99d223b8ee33ba4019af82adf1c48/LittleBigMouse.Plugins/LittleBigMouse.Plugin.Vcp.Avalonia/HisenseVidaa/VidaaMqttConnection.cs#L242-L278","documentation":"Thrown by ReadByteAsync when a read from the TV's MQTT stream returns zero bytes (EndOfStream), meaning the remote peer closed the connection. The library translates this into EndOfStreamException('VIDAA closed the MQTT connection.') so callers know the TV ended the session rather than the read failing locally.","triggerScenarios":"ReadByteAsync, called by the packet-header reader and ReadPacketAsync (ConnectAsync handshake or the ongoing read loop), gets a 0-byte result from stream.ReadAsync — the TV closed the TCP connection mid-handshake or during the session.","commonSituations":"TV powered off, went to standby, or rebooted; Wi-Fi/network interruption terminating the TCP session; TV closing idle connections due to keep-alive timeout; broker crash or firmware restart of the MQTT service.","solutions":["Reopen the connection: catch EndOfStreamException, dispose the dead session, and call OpenMqttAsync again (optionally with backoff).","Send periodic MQTT PINGREQ (the library's PingLoopAsync) so keep-alive requirements don't cause the TV to drop idle connections.","Verify the TV is powered on, awake (not deep standby), and reachable on the network before reconnecting.","Check for recurring drops at fixed intervals — that pattern indicates a keep-alive/idle timeout to tune rather than a transient fault."],"exampleFix":"// before: single attempt, failure ends the session\nawait connection.OpenMqttAsync(token);\n// after: reconnect with backoff when the TV closes the socket\ntry { await connection.OpenMqttAsync(token); }\ncatch (EndOfStreamException)\n{ await Task.Delay(TimeSpan.FromSeconds(2), token); await connection.OpenMqttAsync(token); }","handlingStrategy":"retry","validationCode":"// Probe reachability before (re)connecting\ncanConnect = await PingDeviceAsync(tvHost, timeoutMs: 1000); // TV must be on and reachable","typeGuard":"bool IsRemoteClosed(Exception e) => e is EndOfStreamException;","tryCatchPattern":"try { await connection.OpenMqttAsync(token); }\ncatch (EndOfStreamException)\n{ await Task.Delay(backoff, token); await connection.OpenMqttAsync(token); }","preventionTips":["Run the keep-alive ping loop so the TV doesn't drop idle connections","Expect drops on TV standby/power-off and auto-reconnect when it wakes","Check network stability (Wi-Fi signal, AP isolation) for recurring disconnects","Use exponential backoff to avoid hammering the TV during outages"],"tags":["mqtt","connection-closed","end-of-stream","network","iot"],"backgroundTag":"broken-pipe","analyzedSha":"7a42f01d47d99d223b8ee33ba4019af82adf1c48","analyzedAt":"2026-09-16T00:35:00.514Z","contentChangedAt":"2026-09-16T00:35:00.514Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}