物联网: 我需要使用MQTT还是HTTP?

11

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

该设备未连接到任何电源,但具有电池和太阳能电池板进行充电。

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

虽然我不是这个领域的专家,但如果需要让设备始终可以接收来自主题的消息,则MQTT应该是一个很好的选择。但在我的情况下,它仅读取传感器并周期性地将数据发送到服务器。

目前,我通过HTTP发送数据,但我想知道是否有必要实现MQTT? 我是否可以从MQTT中获得优势以满足我的需求?


1
你可能会发现IoT网站上的这个问题很有趣。如果在Stack Overflow上没有得到任何答案,你也可以在那里提问——IoT网站可能更专注于你感兴趣的方面。 - Aurora0001
4个回答

27

关于MQTT和HTTP之间的比较已经有大量的文献,您可以深入了解其细节,但以下是一些适用于您应用程序的要点。

MQTT

  • MQTT允许持久连接,可以在使用SSL时节省大量资源。如果您只发送少量指标,则MQTT通常比HTTP更有效率。
  • 由于MQTT旨在传递数据(而不是整个页面),所以其发布/订阅模型提供了许多有用的内置功能,如保留和最后的遗嘱。
  • 此外,MQTT提供了一种实现加密、身份验证和访问控制的简单方法。
  • MQTT适用于连接可能间歇性或不可靠的情况。其各种服务质量级别为您提供了确保数据可靠发送的重要方式。
  • 在更大的应用中,MQTT代理提供了更容易管理的方式。我特别喜欢它具有用于衡量性能的标准化指标集。
  • MQTT的主题/子主题值结构有助于组织数据,并使其易于扩展并在多个项目之间共享资源。
  • 虽然这可能是个人偏好,但与使用HTTP相比,我发现MQTT协议更易于理解、排除故障和编程。特别是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


5
我们已经从性能和能耗两个角度测试了 MQTT vs HTTP(REST)在普通服务器和树莓派板子上的表现。结果取决于使用案例和运行进程的设备。
关于您的使用案例,我们也有特殊的测试,即通过HTTP、HTTP-batch或MQTT传递多个消息(多个探针)。结果很简单,如果您有可能在一个HTTP请求中发送数据,那么这将是最佳选择。MQTT排名第二,每个消息传递的HTTP比MQTT效率低得多,速度也更慢。

1
我是新手,但我喜欢使用mqtt来收集数据并将信息发送到设备。
我正在使用synapses rf200芯片(自修复网状网络),并通过串行连接rf200之一到esp8266 wifi芯片来构建桥接。
基本上,我有mqtt_in和mqtt_out作为主题,我的c# xamarin iOs/android应用程序连接到mqtt代理请求从rf200的信息使用mqtt_in(进入rf200网状网络),节点使用mqtt_out(离开rf200网状网络)响应。我将所有信息作为字符串进行解析,并根据需要将其转换为任何我需要的格式。
它的开销非常低,并且mqtt代理非常容易设置。

-2
我认为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);
        }
    });
}

}


这并没有回答到所问的问题。 - hardillb

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接