Azure / azure-iot-sdk-node

A Node.js SDK for connecting devices to Microsoft Azure IoT services
https://docs.microsoft.com/en-us/azure/iot-hub/
Other
261 stars 226 forks source link

Struggling with build errors in Angular 12 #1176

Closed vishnureddy17 closed 1 year ago

vishnureddy17 commented 1 year ago

Discussed in https://github.com/Azure/azure-iot-sdk-node/discussions/1175

Originally posted by **robertmazzo** December 22, 2022 **Bottom line:** I can successfully run your TypeScript/JavaScript Iot Device samples from a cmd prompt with node, but integrating within an **_Angular 12_** project throws many build errors. I'm also reading through this Angular-specific thread re; webpack breaking changes - https://github.com/angular/angular-cli/issues/20819 - but nothing has worked so far. ex/ `BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.` If you want to include a polyfill, you need to: - add a fallback 'resolve.fallback: { "os": require.resolve("os-browserify/browser") }' - install 'os-browserify' I have essentially npm installed the following in my angular proj: "azure-iot-common": "^1.13.1", "azure-iot-device": "^1.18.1", "azure-iot-device-mqtt": "^1.16.1", And the moment when I enable this line of code within my **_iot-device-test service_** in **Angular 12**, the build just blows up: ` this.client = Client.fromConnectionString(this.deviceConnectionString, Protocol);` with the following imports: `import { Client } from 'azure-iot-device'; import { MqttWs as Protocol } from 'azure-iot-device-mqtt';` I've also tried adding this to the "paths" property of "compilerOptions" within my tsconfig.json: ` "assert": ["./assert.ts"]` as well as npm installing 'os-browserify' and `stream-browserify`. In any case, if you have any guidance for me in the meantime I'd appreciate. And I'll keep this thread updated as I gather more info/tips. regards, Bob
vishnureddy17 commented 1 year ago

Hi @robertmazzo, unfortunately our SDK doesn't support browers or brower-like environments (such as Electron). You might be able to get it working. However, we don't develop or test for that scenario, and we wouldn't be able to provide support for it.

robertmazzo commented 1 year ago

@vishnureddy17 - Hello and thank you for your reply. Initially I was under the impression that it would work something like the SignalR TypeScript client, which works in the browser. But now I see this IotHub ts client only runs with node in a server environment or on a local machine. I think I read somewhere that SignalR also integrates with the Azure Iot Hub. Do you think that might be a full solution for my requirements ? In other words, we are looking to connect multiple computers as Iot Devices; these are on a LAN and behind a firewall. These computers need to send out messages, as well as a heartbeat to Azure to say that they are alive (possible using the Iot .Net Windows client). But we also need a web-based admin monitoring tool with ability to read those Iot Hub messages somehow. thank you again. Regards, Bob

anthonyvercolano commented 1 year ago

@robertmazzo I'm not familiar with the SignalR client.

Are you sending the "I'm alive" as a telemetry event? Assuming that you don't do any routing of the telemetry events, consider using the azure event hub library. They have extensive browser support. There is a sample in the source repo that shows how to convert an IoT Hub connection string to an eventhub connection string.

robertmazzo commented 1 year ago

@anthonyvercolano Our full heartbeat (aka "I'm alive") and monitoring feature is not fully developed yet, as I am still researching solutions in the context of the MQTT messages protocol. So no, we are NOT yet sending any telemetry events as of yet. All we have now is a web-based admin/config dashboard where the user can "ping" one of the machines by pressing a button. It calls a RESTful API, which returns a response accordingly.

However, we'd like a full solution which entails 1) publishing regular heartbeat messages from our "devices" (i.e. computers on a LAN and behind the firewall), and 2) allowing a web-based admin to regularly check the status of all "devices" by checking Notifications stored in the Hub. 3) Sending Json/Xml formatted messages from the Web App (hosted in Azure) down to our computers behind the LAN.

So if I understand correctly, our solutions needs 1) Azure Hub (Iot or Event Hub), 2) the Hub CLIENT running on each of the devices (i.e. publish to Azure Hub and also subscribe to those Hub messages), as well as the web-based Hub client in order to read those Hub messages.

robertmazzo commented 1 year ago

@anthonyvercolano and @vishnureddy17 as a side note, we do currently have a SignalR solution which allows us to push messages from Azure Web App and REST API layer down to our machines behind the firewall, however it is often BREAKING. We don't know why, but the connection is often lost. This results in many important messages getting lost. As a result, our client needs to contact our support dept for assistance. One of our other product teams has begun to implement MQTT, so we'd like to follow suit. And I see that the Iot Hub support various protocols, one being MQTT. Hopefully the Event Hub also support mqtt, and perhaps a better fit for our scenario....thank you again.

anthonyvercolano commented 1 year ago

@robertmazzo As best I can recall, to read the data from the event hub, you must use AMQP.

Azure IoT Hub does provide the ability to route the event messages to something other than event hubs. You should look under the routing documentation.

Are these exclusively the features that you would be using for the IoT Hub?

robertmazzo commented 1 year ago

The features I listed above would be implemented using either IoT Hub, Event Hub, Signalr, etc. It depends on what works best for us. It doesn't necessarily have to implement MQTT - AMQT will probablly also work for us; we just need something stable that supports .Net clients, and a Javascript client in the browser.

I.e. One use-case is that a Windows computer behind the LAN is "listening" for incoming messages which come from the Web App (hosted in Azure). Once those messages are consumed, we can pass them off to a REST API installed on those same boxes (currently this feature is breaking in the context of a SignalR connection from Azure to those client machines on the LAN). i.e. Another use-case is the heartbeat or "am I alive" scenario we discussed above. In this case our machines on the LAN (aka "devices") will broadcast messages to the Hub (which can subsequently be consumed by our .Net or Web App clients).

Do you have a suggestion that would allow us to implement a Notifications Hub in Azure, with both Windows clients (behind a firewall) and web clients ? Thank you.

anthonyvercolano commented 1 year ago

@robertmazzo Sorry for the delay in response.

I can mostly at this point talk about issues you need to think about.

If your device side applications are always going to stay attempt to stay connected to the hub, using the MQTT protocol, the application will by default be sending it's own keep alive message every 180 seconds, by default, from the device to the hub. You will never see them. They are tiny messages, I think about 10 bytes of data. This necessary BY protocol. These keep alive messages might only be sent if you haven't sent your own messages in the past 180 seconds. I don't recall right now.

You would still get charged for this potentially if your going over cellular. And I believe this gets counted as part of your message charges by azure.

I don't really think cloud to device (c2d) messages are a great solution with MQTT because you won't actually get a response back that you would see if using AMQP protocol.

You might consider using device methods (which is basically an unstructured RPC). You can pass arguments and receive results. They are synchronous though. However, you can specify timeouts so you won't be held up for long and it's a pretty immediate way to see if the device is alive.

The number of devices you will be dealing with from this dashboard is worth concern. 10 or 20? 100? More the 1000? Small number would be fairly easy to service from the web with synchronous calls.

Not sure about using telemetry here to indicate device alive. You indicate that you want to be able to have a button push. There seems to be a duplication of effort doing a button push and searching for the latest telemetry. Also the telemetry costs money.

Have you looked at this connection status article?

If you have a relatively small number of devices you are attempting to communicate with you might look at a combo solution of device method calls and event grid monitoring (see above article).

robertmazzo commented 1 year ago

@anthonyvercolano Thank you again for responding. And yes, the num of devices on the LAN is generally quite small for most clients (less than 10). Larger clients still probably less than 50 devices.

In addition, the "push button" approach is an option we currently have in one of our admin screens (it's just an API call, and we wait for a response). However we want to replace that manual method with a more robust monitoring tool to check the status of our devices.

In any case, we will still need a push button feature for certain reports/messages that need to be send from Azure down to a machine on the LAN; this is the on-demand feature message feature which is currently breaking at the moment in the context of our SignalR solution.

In any case, I'm looking into Azure Event Hubs at the moment. I got the simple .Net Core sample code working (and sending messages to the Hub portal), but the TypeScript client in my Angular application proves to be a real big headache. It's breaking in WebPack 5, even after installing add'l packages and adding polyfills, etc.

My current issue is posted here under the Azure SDK github - https://github.com/Azure/azure-sdk-for-js/issues/24431

anthonyvercolano commented 1 year ago

@robertmazzo If you have more questions, feel free to open another issue.