Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MQTT-over-Websocket connection reconnects every 30 seconds (MAUI regression) #1983

Open
janusw opened this issue Apr 30, 2024 · 1 comment
Open
Labels
bug Something isn't working

Comments

@janusw
Copy link

janusw commented Apr 30, 2024

Describe the bug

I have a mobile app (previously Xamarin.Forms, now MAUI) which connects to an ActiveMQ Artemis broker via MQTT over (secure) WebSocket, using MQTTNet v4.3.3. With Xamarin.Forms this always worked well, but after switching to MAUI (.NET 7 or 8), I see the following error every 30 seconds, leading to a reconnection:

MQTTnet.Exceptions.MqttCommunicationException: The remote party closed the WebSocket connection without completing the close handshake.
 ---> System.Net.WebSockets.WebSocketException (2): The remote party closed the WebSocket connection without completing the close handshake.
   at System.Net.WebSockets.ManagedWebSocket.ThrowEOFUnexpected()
   at System.Net.WebSockets.ManagedWebSocket.EnsureBufferContainsAsync(Int32 minimumRequiredBytes, CancellationToken cancellationToken)
   at System.Runtime.CompilerServices.PoolingAsyncValueTaskMethodBuilder`1.StateMachineBox`1[[System.Threading.Tasks.VoidTaskResult, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.Net.WebSockets.ManagedWebSocket.<EnsureBufferContainsAsync>d__75, System.Net.WebSockets, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]].System.Threading.Tasks.Sources.IValueTaskSource.GetResult(Int16 token)
   at System.Net.WebSockets.ManagedWebSocket.<ReceiveAsyncPrivate>d__64`1[[System.Net.WebSockets.WebSocketReceiveResult, System.Net.WebSockets, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]].MoveNext()
   at System.Runtime.CompilerServices.PoolingAsyncValueTaskMethodBuilder`1.StateMachineBox`1[[System.Net.WebSockets.WebSocketReceiveResult, System.Net.WebSockets, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a],[System.Net.WebSockets.ManagedWebSocket.<ReceiveAsyncPrivate>d__64`1[[System.Net.WebSockets.WebSocketReceiveResult, System.Net.WebSockets, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]], System.Net.WebSockets, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]].System.Threading.Tasks.Sources.IValueTaskSource<TResult>.GetResult(Int16 token)
   at System.Threading.Tasks.ValueTask`1.ValueTaskSourceAsTask.<>c[[System.Net.WebSockets.WebSocketReceiveResult, System.Net.WebSockets, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]].<.cctor>b__4_0(Object state)
--- End of stack trace from previous location ---
   at MQTTnet.Implementations.MqttWebSocketChannel.ReadAsync(Byte[] buffer, Int32 offset, Int32 count, CancellationToken cancellationToken)
   at MQTTnet.Adapter.MqttChannelAdapter.ReadFixedHeaderAsync(CancellationToken cancellationToken)
   at MQTTnet.Adapter.MqttChannelAdapter.ReceiveAsync(CancellationToken cancellationToken)
   at MQTTnet.Adapter.MqttChannelAdapter.ReceivePacketAsync(CancellationToken cancellationToken)
   --- End of inner exception stack trace ---
   at MQTTnet.Adapter.MqttChannelAdapter.WrapAndThrowException(Exception exception)
   at MQTTnet.Adapter.MqttChannelAdapter.ReceivePacketAsync(CancellationToken cancellationToken)
   at MQTTnet.Client.MqttClient.Receive(CancellationToken cancellationToken)
   at MQTTnet.Client.MqttClient.ReceivePacketsLoop(CancellationToken cancellationToken)

I have observed such errors when running on Android or iOS. They also occur if I continuously transmit data (either sending or receiving).

Which component is your bug related to?

  • ManagedClient

Code example

I'm basically setting up the client like this:

            options = new ManagedMqttClientOptionsBuilder()
                .WithAutoReconnectDelay(TimeSpan.FromSeconds(10))
                .WithClientOptions(new MqttClientOptionsBuilder()
                    .WithWebSocketServer(o => o.WithUri(url))
                    .WithCredentials(user, token)
                    .WithTlsOptions(o => o.UseTls().WithSslProtocols(SslProtocols.None))
                    .Build())
                .Build();

            client = new MqttFactory().CreateManagedMqttClient();

            await client.StartAsync(options);

Workaround

I found that the problem goes away if I use .WithKeepAliveInterval(TimeSpan.Zero) on the WebSocket. It somehow seems to be related to the WebSocket keepalive interval (which is 30s by default).

@janusw janusw added the bug Something isn't working label Apr 30, 2024
@janusw
Copy link
Author

janusw commented May 3, 2024

This issue is somewhat similar to #1691: The error message is the same, but the reconnection interval and also the workaround is different, so I assume it has a different root cause.

However, in #1691 (comment) @logicaloud reports that he can reproduce the problem, but only the KeepAliveInterval workaround works for him, not the MaxServicePointIdleTime one.

I really wonder what could cause this strange phenomenon, and why it's different between Xamarin/NetStandard and MAUI/.NET8. Maybe some behavior of System.Net.Websockets has changed?

Further ideas, anyone? Anything else I can do to debug this? @chkr1011

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant