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

时间:2017-05-19 16:29:25

标签: http mqtt iot

我正在研究一种能够感知和收集环境信息的设备,如温度,湿度等。

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

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

我不是这方面的专家,但我认为MQTT应该是一个不错的选择,如果设备需要始终可以从主题接收消息,但在我的场景中它只读取传感器,并发送数据定期发送到服务器。

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

4 个答案:

答案 0 :(得分:12)

有关MQTT与HTTP的丰富文献,您应该深入研究细节,但这里有一些适合您应用的要点。

MQTT

  • MQTT允许持久连接,这可以通过HTTP节省大量资源。如果您使用SSL,这是最相关的。
  • 如果您只发送一些指标,MQTT通常比HTTP更具带宽效率。
  • 由于MQTT旨在提供数据(而不是整个页面),因此其发布/订阅模型提供了许多有用的内置功能,例如保留和最后一次。
  • 此外,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

答案 1 :(得分:2)

我们已经从正常服务器和Raspberry Pi主板上测试了MQTT vs HTTP(REST)来自性能和能耗的测试。结果取决于进程运行的用例和设备。

关于您的用例我们还有特殊测试=>通过HTTP,HTTP批处理或MQTT提供许多消息(多个探测)。如果您有可能在一个HTTP请求中发送数据,结果非常简单 - 这将是最佳选择。 MQTT位居第二,HTTP和每个消息传递的功效要低得多,而且比MQTT慢。

答案 2 :(得分:1)

我是游戏新手,但我喜欢mqtt收集数据和向设备发送信息。

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

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

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

答案 3 :(得分:-2)

  
    

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

  
公共类PahoMqttClient {

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

private String 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);
        }
    });
}

}