Azure-Samples / MqttApplicationSamples

Samples implementing common PubSub patterns for Edge and Cloud Brokers
MIT License
25 stars 25 forks source link

Exception: ' Received an unexpected EOF or 0 bytes from the transport stream.' #75

Closed sandervandevelde closed 11 months ago

sandervandevelde commented 11 months ago

Please provide us with the following information:

This issue is for a: (mark with an x)

- [ X] bug report -> please search issues before submitting

Minimal steps to reproduce

Fill in the environment variables; create a .net7 console app; Use the three lines of sample code; compile successfully; run.

Any log messages given by the failure

MQTTnet.Exceptions.MqttCommunicationException: ' Received an unexpected EOF or 0 bytes from the transport stream.'

ClientConsoleApp Warning: 0 : EnvFile Not found in path C:\git\MqttApplicationSamples\mqttclients\dotnet\ClientConsoleApp\bin\Debug\net7.0 .env ClientConsoleApp Information: 0 : Loaded Cert: CN=client10-authn-ID XYZ issued by CN=MqttBlogAppSamplesCA Intermediate CA, O=MqttBlogAppSamplesCA, not after: 26/01/2024 11:37:12 ClientConsoleApp Information: 0 : >> [1]: Trying to connect with server 'iotgrid-test-egns.westeurope-1.eventgrid.azure.net:8883' ClientConsoleApp Information: 0 : >> [8]: Error while connecting with server MQTTnet.Exceptions.MqttCommunicationException: Received an unexpected EOF or 0 bytes from the transport stream. ---> System.IO.IOException: Received an unexpected EOF or 0 bytes from the transport stream. at System.Net.Security.SslStream.ReceiveBlobAsync[TIOAdapter](CancellationToken cancellationToken) at System.Net.Security.SslStream.ForceAuthenticationAsync[TIOAdapter](Boolean receiveFirst, Byte[] reAuthenticationData, CancellationToken cancellationToken) at MQTTnet.Implementations.MqttTcpChannel.ConnectAsync(CancellationToken cancellationToken) at MQTTnet.Implementations.MqttTcpChannel.ConnectAsync(CancellationToken cancellationToken) at MQTTnet.Adapter.MqttChannelAdapter.ConnectAsync(CancellationToken cancellationToken) --- End of inner exception stack trace --- at MQTTnet.Adapter.MqttChannelAdapter.WrapAndThrowException(Exception exception) at MQTTnet.Adapter.MqttChannelAdapter.ConnectAsync(CancellationToken cancellationToken) at MQTTnet.Client.MqttClient.ConnectInternal(IMqttChannelAdapter channelAdapter, CancellationToken cancellationToken) at MQTTnet.Client.MqttClient.ConnectAsync(MqttClientOptions options, CancellationToken cancellationToken) ClientConsoleApp Information: 0 : >> [8]: Disconnecting [Timeout=00:01:40] ClientConsoleApp Information: 0 : >> [8]: Disconnected from adapter. ClientConsoleApp Information: 0 : >> [8]: Disconnected.

Expected/desired behavior

connected client

Language

C#

OS and Version?

Windows

Mention any other details that might be useful

Device registration and cert works for MQTTX (tested separately, not running at the same time).


Thanks! We'll be in touch soon.

rido-min commented 11 months ago

Seems like your app is not loading the .env file, and not sure how the client cert is loaded. I'm adding a note to produce a better error message for this case.

Can you try with the getting_started scenario? make sure you follow the exact instructions (running the app from the same folder with the .env file, and the pem/key files.)

If you are running in VS, you can also specify the envvars from the launchSettings.json, or alternatively you can pass the .env path to MqttConnectionSettings.CreateFromEnvVars()

rido-min commented 11 months ago

I tried to connect to your endpoint, and found the endpoint has not TLS enabled.

Make sure that:

  1. MQTT is enabled in your EventGrid Namespace
  2. You are using the MQTT endpoint az resource show --ids $res_id --query "properties.topicSpacesConfiguration.hostname"
rido-min commented 11 months ago

@Hi @sandervandevelde did you check if the endpoint was the right one? an easy way to check it supports TLS is by using openssl s_client -connect

rido-min commented 11 months ago

@sandervandevelde any updates?

sandervandevelde commented 11 months ago

Hello @rido-min , I tried a number of things but I did not have any success. I landed here because of the samples link seen on the EventGrid MQTT support docs. The MQTT clients section seems quite ok regarding the documentation of the environment variables. I skipped the getting started because it seems to be focused on some local Mosquitto server? I have to perform some 'cat' to create a certificate string for Mosquitto (is this 'cat' working in Powershell)? But it's also mentioning the Eventgrid? All I want is a sample in C# of an MQTT client capable of connecting to the 'IoTGrid' in 20-30 lines, while sending some messages to a topic. This should be on par with the setting I need to set in the MQTTX example. The MQTTnet extensions seen here look pretty well designed but it is overwhelming.

rido-min commented 11 months ago

@sandervandevelde

Seems to me you are trying to connect to the wrong Event Grid endpoint. Each event grid instance has two endpoints, one for HTTP as <instance.region>-1.eventgrid.azure.net and another for MQTT as <instance.region>-ts.eventgrid.azure.net.

Can you double check you are using the same endpoint as in MQTTX ?

All the samples in this repo are designed to work with different brokers, and adapting to different authentication options.

Since EventGrid requires authentication with client certs, we added instructions to create certs using step, cat is just a tool to readfile the file contents and redirect to an output. Both tools work with powershell, however, and due to the C samples requirements, we have prioritized Linux/WSL over Windows.

The MQTTnet extensions seen here look pretty well designed but it is overwhelming.

curious to understand this comment, what is overwhelming? and how can we do it better?

sandervandevelde commented 11 months ago

Hello @rido-min

Success. The client can be connected. I was able to send messages using the extension library.

I found a typo (extra character) in my MQTT URL. I overlooked it twice :-( ).

Regarding that library, it feels quite extensive:

image

It seems to do everything: connecting, requests, responses, commands, and even alerts.

It's more than 700 lines long.

I prefer having separate (little) applications demonstrating one task (one problem, one solution).

But maybe I'm taking MQTT too easy seeing all the serializers, X509 tooling, producers, and consumers.

Thanks for guiding me in the right direction.

rido-min commented 11 months ago

yeah.. we are trying to find a balance to keep the scenarios very focused. We could limit the extensions to "connection only kind of helpers", ands move the Producer/Consumer/Commands to each sample.

The intent here was to allow customers to create new Telemetries, Alerts, or Commands apps reusing these extensions.

We have plans to productize these ideas in a former NuGet package, this is just the starting point.

Can we close this issue now?

sandervandevelde commented 11 months ago

Thanks for the extra explanation. Closed.