amenzhinsky / iothub

Azure IoT Hub SDK for Golang
MIT License
53 stars 58 forks source link

Getting error while sending C2D message via Service Client. (Error: failed to send message: protocol error: received flow without next-incoming-id after session established) #88

Open devak8 opened 2 months ago

devak8 commented 2 months ago

Below is the code used to C2D (Service client Sender)

`package iothub

import ( "context" "fmt" "log"

"github.com/amenzhinsky/iothub/iotservice"

)

// SendMessage sends a message to the specified IoT Hub device. func SendMessage(iotHubConnectionString, deviceID, messageContent string) { // Create a new IoT Hub service client using the connection string client, err := iotservice.NewFromConnectionString(iotHubConnectionString) if err != nil { log.Fatalf("failed to create IoT Hub service client: %v", err) }

// Prepare the message to be sent to the device
// message := &iotservice.Message{
//  Data: []byte(messageContent),
// }

data := []byte(messageContent)

// Send the cloud-to-device message to the specified device

if err := client.SendEvent(context.Background(), deviceID, data); err != nil {
    log.Fatalf("failed to send message: %v", err)
}

fmt.Println("Message sent to device successfully.")

} `

devak8 commented 2 months ago

We are using below modules package:

github.com/amenzhinsky/iothub v0.9.2-0.20230710081242-d4c494d2c439

pedrolemos4 commented 2 months ago

It might be the Transport you are using, your device might be blocking it, try to change it

PremSahooESL commented 2 months ago

What do you mean by transport? Would you please elaborate it more? We are able to send the data from Java Service Client for the same device, but not from this Go Package.

pedrolemos4 commented 2 months ago

Try setting your client like this client, err := iotservice.NewFromConnectionString(iotHubConnectionString, iotservice.WithHTTPClient(http.DefaultClient)) With this you are setting a different way to communicate with iothub. I'm not sure but that might be your issue. If this does not work, check in the library what other method are .With...() and try with those.

PremSahooESL commented 2 months ago

does not it support 'amqps' protocol instead of http?

devak8 commented 2 months ago

client, err := iotservice.NewFromConnectionString(iotHubConnectionString, iotservice.WithHTTPClient(http.DefaultClient))

Above code throws same previously mentioned error, even we tried with other 2 (WithLogger , WithTLSConfig)

do you have any working examples?

pedrolemos4 commented 2 months ago

Show the error

devak8 commented 2 months ago

2024/09/05 16:43:31 failed to send message: protocol error: received flow without next-incoming-id after session established

pedrolemos4 commented 2 months ago

I think your issue is because you are using iotservice to send a message. This should be turned flow 1- Create a Device in Iothub using iotservice lib 2- Create a client for the device using iotclient lib 3- Connect and send a event using the device's client

PremSahooESL commented 2 months ago
1. IotHub device is already created.
2. Now we need to send data from C2D (Cloud to Device) for the specific device.
3. So we must use Service client library with IotHub service connection string, device ID and payload.
4. This is the Service Client's responsibility to send message to IotHub  for the specific Device.
PremSahooESL commented 2 months ago

If IoTHub Device wants to send message (D2C), then it must use Device Client. Our case is just opposite of it.

PremSahooESL commented 2 months ago

Could you please provide working sample code of Service Client sender, if you have any?

pedrolemos4 commented 2 months ago

You're right. I read wrong First things first, you can send a message from the iothub to the device?

PremSahooESL commented 2 months ago

yes, true.

PremSahooESL commented 2 months ago

From Azure portal we can directly send a C2D message for specific device. And the device receives the data without any issue. But we can not send the same data by using GoLang Service Client lib.

But it works from Java Service Client

PremSahooESL commented 2 months ago

is there any thing wrong with the amqp protcol version?

devak8 commented 2 months ago

Hey , if you have any sample code for that specific library for the C2D communication , then please provide , or any pseudo code ?

devak8 commented 2 months ago

Hi please give some updates about the above thread??

devak8 commented 2 months ago

@amenzhinsky please have a look into the above issue in thread.

devak8 commented 2 months ago

Hi @pedrolemos4 please do some comment on the above thread , it's getting blocker for me Thanks in advance !

devak8 commented 2 months ago

Hi Folks ! Is there any update on the above issue thread , please give your insight on this. is there any issue with the library : github.com/amenzhinsky/iothub/iotservice message is not getting sent (C2D communication)

devak8 commented 2 months ago

is there any issue with AMQP with this library i am using : github.com/amenzhinsky/iothub/iotservice

getting this error only : received flow without next-incoming-id after session established

devak8 commented 2 months ago

Or is there some setting that needs to be configured in the IoT Hub to prevent this from happening? : protocol error: received flow without next-incoming-id after session established

I would really appreciate if someone is able to jump on this one.

PremSahooESL commented 2 months ago

var fixedIncomId uint32 = 12345
var nIncomIdPtr *uint32 = &fixedIncomId

case *frames.PerformFlow:
                body.NextIncomingID = nIncomIdPtr

                if body.NextIncomingID == nil {
                    // This is a protocol error:
                    //       "[...] MUST be set if the peer has received
                    //        the begin frame for the session"
                    closeWithError(&Error{
                        Condition:   ErrCondNotAllowed,
                        Description: "next-incoming-id not set after session established",
                    }, errors.New("protocol error: received flow without next-incoming-id after session established"))
                    continue
                }
PremSahooESL commented 2 months ago

in Azure/go-amqp/session.go file

body.NextIncomingID == nil

above condition expects some uint32 type NextIncomingID Generally when iotservice sends message, it is always nil, so we were getting the error 'protocol error: received flow without next-incoming-id after session established'

I just made it to a hardcoded value '12345'. Now we got rid of this error.

PremSahooESL commented 2 months ago

Do not know though, how to pass body.NextIncomingI value as non-nil while sending the message (C2D)