【问题标题】:IoT: do I need to use MQTT or HTTP?IoT:我需要使用 MQTT 还是 HTTP?
【发布时间】:2017-10-19 20:50:14
【问题描述】:

我正在开发一种可以从环境中感知和收集信息(例如温度、湿度等)的设备。

该设备没有连接任何电源,但它有一个电池和一个太阳能电池板来给它充电。

它大部分时间几乎处于深度睡眠状态,只有在需要感知和传输数据时才会醒来。此操作大约需要 1-2 分钟,然后再次进入休眠状态。

我不是这方面的专家,但我认为 MQTT 应该是一个不错的选择,如果设备需要随时接收来自某个主题的消息,但在我的场景中它只读取传感器,然后发送定期向服务器发送数据。

目前我正在通过 HTTP 发送数据,但我想知道实现 MQTT 是否有意义?在这种情况下,我应该比 HTTP 获得任何优势吗?

【问题讨论】:

  • 您可能会在 IoT 网站上发现 this question 值得一读。如果您在 Stack Overflow 上没有得到任何答案,您也可以在那里提问——物联网网站可能更专注于您感兴趣的部分。

标签: http mqtt iot


【解决方案1】:

有大量关于 MQTT 与 HTTP 的文献,您应该深入研究以了解详细信息,但这里有一些适用于您的应用程序的要点。

MQTT

  • MQTT 允许持久连接,这可以通过 HTTP 节省大量资源。如果您使用的是 SSL,这一点最为相关。
  • 如果您只发送几个指标,MQTT 通常会比 HTTP 更节省带宽。
  • 由于 MQTT 是为交付数据(不是整个页面)而设计的,它的 pub/sub 模型提供了许多有用的内置功能,例如保留和最后遗嘱。
  • MQTT 还提供了一种实现加密、身份验证和访问控制的简单方法。
  • MQTT 适用于您的连接可能断断续续或不可靠的情况。其各种服务质量级别为您提供了确保数据可靠发送的重要方法。
  • 根据我的经验,在较大的应用程序中,MQTT 代理提供了更轻松的管理。我特别喜欢有一套用于衡量绩效的标准化指标。
  • MQTT 的主题/子主题值结构有助于组织您的数据,并可以轻松地在多个项目之间进行扩展和共享资源。
  • 这可能是个人喜好,但我发现 MQTT 协议比使用 HTTP 更易于理解、故障排除和编程。特别是,Python Paho MQTT 库简单且运行良好。

总之,MQTT 有许多似乎非常适合您的应用程序的功能。也就是说,您可能会使用 HTTP 复制其中的许多,但这需要更多的工作。

HTTP

  • 几乎所有地方都支持,确保更容易与防火墙兼容。如果您在不受控制的网络上进行部署,这可能很重要。

  • 这是一种更常见的协议,因此您(和您的最终用户)可能已经对它感到满意。同样,您可能已经了解了更容易保护的安全模型。

  • 不同的 MQTT 实现之间存在一些差异,这可能会导致困难(例如,我使用 Mosquitto,有时当人们谈论他们的 HiveMQ 设置时会感到困惑)。 HTTP 让我觉得更通用,并且有一个更大的社区可以帮助你。

因此,与 MQTT 相比,HTTP 具有一些固有的缺点,但如果 MQTT 的特定功能不吸引您,它会完成工作并且可能更实用。

但是,如果这是一个大型项目,那么在您的特定应用程序和环境中尝试并运行一些基准测试和测试是值得的。建立一个测试环境并获得一些指标并不难。如果这更像是一个爱好/一次性项目,那么我会使用您更喜欢或觉得更有趣的任何一个。

来源/进一步阅读:

http://stephendnicholas.com/posts/power-profiling-mqtt-vs-https https://www.ibm.com/developerworks/community/blogs/sowhatfordevs/entry/using_mqtt_protocol_advantages_over_http_in_mobile_application_development5?lang=en https://medium.com/@shubhanshusingh/http-vs-mqtt-9008d448bf88 https://www.slideshare.net/paolopat/mqtt-iot-protocols-comparison https://mobilebit.wordpress.com/2013/05/03/rest-is-for-sleeping-mqtt-is-for-mobile/ http://bec-systems.com/site/1200/iot-protocols-mqtt-vs-coap-vs-http

【讨论】:

    【解决方案2】:

    我们从性能和能耗的角度对普通服务器和 Raspberry Pi 板的 SSL 上的 MQTT vs HTTP(REST) 进行了测试。结果取决于运行进程的用例和设备。

    关于您的用例,我们也有特殊测试 => 通过 HTTP、HTTP-batch 或 MQTT 传递许多消息(多个探测)。结果非常简单,如果您有可能在一个 HTTP 请求中发送数据 - 这将是最佳选择。 MQTT 排在第二位,与 MQTT 相比,按消息传递的 HTTP 的能源效率和速度要低得多。

    【讨论】:

      【解决方案3】:

      我是游戏新手,但我喜欢使用 mqtt 收集数据并将信息发送到设备。

      我正在使用突触 rf200 芯片(自我修复网状网络),我通过将其中一个 rf200 串行连接到 esp8266 wifi 芯片来构建一个桥接器。

      基本上,我将 mqtt_in 和 mqtt_out 作为主题,我的 c# xamarin iOs/android 应用程序连接到 mqtt 代理,使用 mqtt_in(进入 rf200 网状网络)从 rf200 请求信息,节点使用 mqtt_out(在 rf200 外)进行响应网状网络)我收集所有信息作为必要的字符串解析并将其转换为我需要的任何内容。

      开销非常低,而且 mqtt 代理很容易设置。

      【讨论】:

        【解决方案4】:

        我认为 MQTT 最适合你..你可以使用 eclipse paho 库.. 这门课可能对你有帮助。

        公共类 PahoMqttClient {

        private static final String TAG = "PahoMqttClient";
        private MqttAndroidClient mqttAndroidClient;
        

        私有字符串 broker_userName,broker_password; public MqttAndroidClient getMqttClient(Context context, String brokerUrl, String clientId,String broker_password) {

            this.broker_userName=clientId;
            this.broker_password=broker_password;
        
            mqttAndroidClient = new MqttAndroidClient(context, brokerUrl, clientId);
            try {
                IMqttToken token = mqttAndroidClient.connect(getMqttConnectionOption(), null, new IMqttActionListener() {
                            @Override
                            public void onSuccess(IMqttToken iMqttToken) {
                                Log.d(TAG, "Success");
                            }
        
                            @Override
                            public void onFailure(IMqttToken iMqttToken, Throwable exception) {
                                Log.d(TAG, "Failure " + exception.toString());
        
                            }
                        });
        
        
            } catch (MqttException e) {
                e.printStackTrace();
            }
        
            return mqttAndroidClient;
        }
        
        public void disconnect(@NonNull MqttAndroidClient client) throws MqttException {
            IMqttToken mqttToken = client.disconnect();
            mqttToken.setActionCallback(new IMqttActionListener() {
                @Override
                public void onSuccess(IMqttToken iMqttToken) {
                    Log.d(TAG, "Successfully disconnected");
                }
        
                @Override
                public void onFailure(IMqttToken iMqttToken, Throwable throwable) {
                    Log.d(TAG, "Failed to disconnected " + throwable.toString());
                }
            });
        }
        
        @NonNull
        private DisconnectedBufferOptions getDisconnectedBufferOptions() {
            DisconnectedBufferOptions disconnectedBufferOptions = new DisconnectedBufferOptions();
            disconnectedBufferOptions.setBufferEnabled(true);
            disconnectedBufferOptions.setBufferSize(100);
            disconnectedBufferOptions.setPersistBuffer(false);
            disconnectedBufferOptions.setDeleteOldestMessages(false);
            return disconnectedBufferOptions;
        }
        
        @NonNull
        private MqttConnectOptions getMqttConnectionOption() {
            MqttConnectOptions mqttConnectOptions = new MqttConnectOptions();
            mqttConnectOptions.setCleanSession(false);
            mqttConnectOptions.setAutomaticReconnect(true);
            mqttConnectOptions.setKeepAliveInterval(120);
            //mqttConnectOptions.setWill(Constants.PUBLISH_TOPIC, "I am going offline".getBytes(), 1, true);
            mqttConnectOptions.setUserName(broker_userName);
            mqttConnectOptions.setPassword(broker_password.toCharArray());
            return mqttConnectOptions;
        }
        
        
        public void publishMessage(@NonNull MqttAndroidClient client, @NonNull String msg, int qos, @NonNull String topic)
                throws MqttException, UnsupportedEncodingException {
            byte[] encodedPayload = new byte[0];
            encodedPayload = msg.getBytes("UTF-8");
            MqttMessage message = new MqttMessage(encodedPayload);
            message.setId(320);
            message.setRetained(false);
            message.setQos(qos);
            try {
                client.publish(topic, message);
            }catch (Exception e){ Log.e("PUB", e.getMessage());}
        
        }
        
        public void subscribe(@NonNull MqttAndroidClient client, @NonNull final String topic, int qos) throws MqttException {
            IMqttToken token = client.subscribe(topic, qos);
            token.setActionCallback(new IMqttActionListener() {
                @Override
                public void onSuccess(IMqttToken iMqttToken) {
                    Log.d(TAG, "Subscribe Successfully " + topic);
                }
        
                @Override
                public void onFailure(IMqttToken iMqttToken, Throwable throwable) {
                    Log.e(TAG, "Subscribe Failed " + topic);
        
                }
            });
        }
        
        public void unSubscribe(@NonNull MqttAndroidClient client, @NonNull final String topic) throws MqttException {
        
            IMqttToken token = client.unsubscribe(topic);
        
            token.setActionCallback(new IMqttActionListener() {
                @Override
                public void onSuccess(IMqttToken iMqttToken) {
                    Log.d(TAG, "UnSubscribe Successfully " + topic);
                }
        
                @Override
                public void onFailure(IMqttToken iMqttToken, Throwable throwable) {
                    Log.e(TAG, "UnSubscribe Failed " + topic);
                }
            });
        }
        

        }

        【讨论】:

        • 这没有回答所提出的问题。
        猜你喜欢
        • 1970-01-01
        • 2011-01-28
        • 1970-01-01
        • 2019-09-09
        • 1970-01-01
        • 1970-01-01
        • 2021-10-24
        • 2015-11-14
        • 2014-04-29
        相关资源
        最近更新 更多