善用桥接MQTT经纪人

我目前正在一个项目上,外部应用程序通过MQTT协议从许多传感器发送数据。

我想收集所有这些数据,并将它们发送到外部服务器。我想创建2个MQTT经纪人:

  • 一个本地(在带有发送数据的应用程序的机器上)
  • 一个在远程服务器中

我将在两者之间建立网桥。我的MQTT服务器应用activeMQ提供了这种可能性(我想这是一个共同的功能)。

通过这种方式,数据生成应用程序将在本地代理上发布,并且通过桥接,相同的数据将在远程代理上发布。关键是让应用程序在连接断开的情况下正常运行。

当我失去经纪人之间的网络连接时,在没有连接的时候,我没有得到应用程序生成的数据。您知道是否可以配置网桥以使其按我想要的方式工作?

我是否必须开发一个小程序来侦听本地代理的所有主题,检测连接丢失,然后将所有丢失的消息重新发送给远程代理?

我从两个代理添加配置文件。我的第一台activeMQ服务器与我的应用程序位于同一台计算机上,第二台activeMQ服务器在同一网络上的另一台计算机上。两台计算机都能互相ping通。

本地经纪人:

<beans
  xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
  http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core.xsd">

    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations">
            <value>file:${activemq.conf}/credentials.properties</value>
        </property>
    </bean>

    <bean id="logQuery" class="io.fabric8.insight.log.log4j.Log4jLogQuery"
          lazy-init="false" scope="singleton"
          init-method="start" destroy-method="stop">
    </bean>

    <broker xmlns="http://activemq.apache.org/schema/core" brokerName="localhost" dataDirectory="${activemq.data}">

        <destinationPolicy>
            <policyMap>
              <policyEntries>
                <policyEntry topic=">" >
                  <pendingMessageLimitStrategy>
                    <constantPendingMessageLimitStrategy limit="1000"/>
                  </pendingMessageLimitStrategy>
                </policyEntry>
              </policyEntries>
            </policyMap>
        </destinationPolicy>

        <managementContext>
            <managementContext createConnector="false"/>
        </managementContext>

        <persistenceAdapter>
            <kahadb directory="${activemq.data}/kahadb"/>
        </persistenceAdapter>

          <systemUsage>
            <systemUsage>
                <memoryUsage>
                    <memoryUsage percentOfJvmHeap="70" />
                </memoryUsage>
                <storeUsage>
                    <storeUsage limit="100 gb"/>
                </storeUsage>
                <tempUsage>
                    <tempUsage limit="50 gb"/>
                </tempUsage>
            </systemUsage>
        </systemUsage>

        <transportConnectors>
            <transportConnector name="mqtt" uri="mqtt://0.0.0.0:1883?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
        </transportConnectors>

        <networkConnectors>
            <networkConnector uri="static:(tcp://192.168.16.100:61616)"/>
        </networkConnectors>

        <shutdownHooks>
            <bean xmlns="http://www.springframework.org/schema/beans" class="org.apache.activemq.hooks.SpringContextHook" />
        </shutdownHooks>

    </broker>

    <import resource="jetty.xml"/>

</beans>

远程经纪人:

<beans
  xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
  http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core.xsd">

    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations">
            <value>file:${activemq.conf}/credentials.properties</value>
        </property>
    </bean>

    <bean id="logQuery" class="io.fabric8.insight.log.log4j.Log4jLogQuery"
          lazy-init="false" scope="singleton"
          init-method="start" destroy-method="stop">
    </bean>

    <broker xmlns="http://activemq.apache.org/schema/core" brokerName="localhost" dataDirectory="${activemq.data}">

        <destinationPolicy>
            <policyMap>
              <policyEntries>
                <policyEntry topic=">" >
                  <pendingMessageLimitStrategy>
                    <constantPendingMessageLimitStrategy limit="1000"/>
                  </pendingMessageLimitStrategy>
                </policyEntry>
              </policyEntries>
            </policyMap>
        </destinationPolicy>

        <managementContext>
            <managementContext createConnector="false"/>
        </managementContext>

        <persistenceAdapter>
            <kahadb directory="${activemq.data}/kahadb"/>
        </persistenceAdapter>

          <systemUsage>
            <systemUsage>
                <memoryUsage>
                    <memoryUsage percentOfJvmHeap="70" />
                </memoryUsage>
                <storeUsage>
                    <storeUsage limit="100 gb"/>
                </storeUsage>
                <tempUsage>
                    <tempUsage limit="50 gb"/>
                </tempUsage>
            </systemUsage>
        </systemUsage>

        <transportConnectors>
            <transportConnector name="openwire" uri="tcp://0.0.0.0:61616?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
            <transportConnector name="mqtt" uri="mqtt://0.0.0.0:1883?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
        </transportConnectors>

        <shutdownHooks>
            <bean xmlns="http://www.springframework.org/schema/beans" class="org.apache.activemq.hooks.SpringContextHook" />
        </shutdownHooks>

    </broker>

    <import resource="jetty.xml"/>

</beans>

为了模拟两个代理之间的断开连接,我只是将第二台计算机与网络断开连接。

我在两台计算机上都使用MQTTBox来订阅我写的主题。这样一来,当我重新连接第二台计算机时,我看到在本地代理中的某个主题上发送的数据没有发布在与远程代理相同的主题上。

编辑:新信息

我今天再次尝试了测试,发现我的MQTT客户端MQTTBox上有一个“保留”复选框。 所以:

  • 在计算机A上,我发布了一条消息,其中主题/ test选中了保留,计算机B正在/#
  • 上监听
  • 连接两台计算机后,它显然运行良好,我在计算机B上看到了消息。
  • 当我断开计算机B的连接时,发布2条消息并选中“保留”,然后重新连接计算机B,我只会看到我发布的2条消息中的最新消息...

更好,但是我也想看看其他消息...如果有人可以帮助我,我迷路了...

我还可以为要发布的消息设置QoS。我尝试在Qos = 0和QoS = 1的情况下进行操作。

hualuofengfei 回答:善用桥接MQTT经纪人

用于消息的QOS也适用于网桥连接。

因此,如果为QOS大于0的主题配置了网桥,则本地代理将在与远程代理的连接断开时将消息排队,并在连接恢复时发送消息。

这样,任何消息都不会丢失。

对于MQTT代理来说,这是完全正常的部署模式。

本文链接:https://www.f2er.com/3080018.html

大家都在问