EMQ (Erlang/Enterprise/Elastic MQTT Broker)

https://www.cnblogs.com/SteveLee/p/9843215.html

MQ介绍

  EMQ (Erlang/Enterprise/Elastic MQTT Broker) 是基于 Erlang/OTP 平台开发的开源物联网 MQTT 消息服务器。Erlang/OTP 是出色的软实时(Soft-Realtime)、低延时(Low-Latency)、分布式(Distributed) 的语言平台。MQTT 是轻量的(Lightweight)、发布订阅模式(PubSub) 的物联网(IoT)消息协议。

订阅(pub)/发布(sub)模式

消息队列中的广播(fanout)模式

轻量化:docker镜像都才88.4MB

一些关于常用EMQTT的快速链接:

官网API地址:http://www.emqtt.com/docs/v2/

开源项目地址:https://github.com/emqtt

Docker安装模式:http://www.emqtt.com/docs/v2/install.html#docker

MQTT介绍和场景:https://www.mqtt.com/

安装过程

假如你的centos上已经安装了Docker,并pull了devicexx/emqttd这个镜像,输入如下命令

docker run -dit --name=sample_emqtt --restart=always -p 18083:18083 -p 1883:1883 -p 8083:8083 -p 8883:8883 998429a869e8

确保映射如下几个端口

1883、8083、8883:这三个是基于EMQTT传输通讯的端口

18083:这个是EMQTT Web控制台的端口

我的虚拟机IP网段是153.132,直接输入http://192.168.153.132:18083进入Web控制台,默认用户名和密码是admin, public

至此EMQTT已经顺利安装完成。

在NET Core中使用EMQ:

emqtt官网没有提供.net的客户端,在nuget和github上找到了实现了MQTT协议的公共组件。

MQTTnet nuget: https://www.nuget.org/packages/MQTTnet/

MQTTnet github: https://github.com/chkr1011/MQTTnet

MQTTnet Client的几个主要事件:

ApplicationMessageReceived:MQTTnet中主要方法事件,当接收到消息的时候,该事件触发。包含Topic,Payload,Qos,Retain主要成员。

Connected:客户端成功连接时触发。

Disconnected:客户端丢失连接时触发。

创建一个发布者

先创建一个发布者Publisher的配置类,代码简单:

复制代码

public static class PublisherConfig

{

///



/// 创建mqtt的客户端接口实例

///

public static readonly IMqttClient Client = new MqttFactory().CreateMqttClient();

    /// <summary>
/// 创建mqtt配置选项
/// </summary>
public static readonly MqttClientOptions ClientOptions = new MqttClientOptions
{
// 通道选项
ChannelOptions = new MqttClientTcpOptions
{
Server = "192.168.153.132"
}, /*
* 客户端ID
* 在MQTTnet框架中,当ClientId未赋值,将使用默认的GUID生成默认的ClientId
*/
ClientId = "Client_publisher", // 客户端认证
Credentials = new MqttClientCredentials
{
Username = "clientUser_01",
Password = "123123"
}
}; public const string Topic = MQTT_Common.Config.Topic.Name;
}

复制代码

为了测试方便,创建了一个全局固定的Topic名称

public static class Topic
{
public const string Name = "/WorldTopic";
}

再创建一个发布者Publisher,代码简单

复制代码

public static class Publisher

{

private static readonly IMqttClient Client = PublisherConfig.Client;

private static readonly MqttClientOptions ClientOptions = PublisherConfig.ClientOptions;

private static readonly string Topic = PublisherConfig.Topic;

    public static void RunAsync()
{
try
{
Console.WriteLine("publisher is running");
CreateConnection();
LoopInput().Wait();
}
catch (Exception exception)
{
Console.WriteLine(exception);
}
} private static void CreateConnection()
{
CommonEventHandler.EventHandler(Client, ClientOptions);
CommonEventHandler.TryConnectionAsync(Client, ClientOptions);
} private static async Task LoopInput()
{
while (true)
{
await Client.SubscribeAsync("/World"); Console.WriteLine("输入消息数据:");
var r = Console.ReadLine(); var applicationMessage = new MqttApplicationMessageBuilder()
.WithTopic(Topic) // 设置主题
.WithPayload(r) // 设置载荷(消息内容)
.WithAtLeastOnceQoS() // 设置质量
.WithRetainFlag(false) // 设置持久化
.Build(); await Client.PublishAsync(applicationMessage);
}
}

复制代码

创建一个或多个订阅者

复制代码

public static class SubscriberConfig01

{

public static readonly IMqttClient Client = new MqttFactory().CreateMqttClient();

    public static readonly MqttClientOptions ClientOptions = new MqttClientOptions
{
ChannelOptions = new MqttClientTcpOptions
{
Server = "192.168.153.132"
},
// 唯一需要修改的Client唯一ID
ClientId = "Client_01",
Credentials = new MqttClientCredentials
{
// 用户可用多个,也可不启用客户端验证
Username = "clientUser_02",
Password = "123123"
}
}; public const string Topic = MQTT_Common.Config.Topic.Name;
}

复制代码

MQTTnet中所有连接端都是Client,所以唯一的变化是ClientID这个值,可使用系统GUID自动生成,也可以使用不同的Client限定名。

复制代码

public static class Subscriber01

{

private static readonly IMqttClient Client = SubscriberConfig01.Client;

private static readonly MqttClientOptions ClientOptions = SubscriberConfig01.ClientOptions;

private static readonly string Topic = SubscriberConfig01.Topic;

    public static async Task RunAsync()
{
try
{
Console.WriteLine("subscriber 1 is running");
CreateConnection();
// 注册/订阅Topic主题
await Client.SubscribeAsync(Topic);
Console.ReadKey();
}
catch (Exception exception)
{
Console.WriteLine(exception);
}
} private static void CreateConnection()
{
CommonEventHandler.EventHandler(Client, ClientOptions);
CommonEventHandler.TryConnectionAsync(Client, ClientOptions);
}
}

复制代码

公共函数CommonEventHandler,用于公共事件处理和连接尝试

复制代码

public static class CommonEventHandler

{

///



/// 添加Client相关事件处理函数

///

/// IMqttClient客户端

/// MqttClientOptions配置选项

/// 主题Topic名称

public static void EventHandler(IMqttClient client, MqttClientOptions clientOptions, string subscribe = "#")

{

client.ApplicationMessageReceived += (s, e) =>

{

Console.WriteLine("### 收到程序消息 ###");

Console.WriteLine($"+ [主题]Topic = {e.ApplicationMessage.Topic}");

Console.WriteLine($"+ [载荷]Payload = {Encoding.UTF8.GetString(e.ApplicationMessage.Payload)}");

Console.WriteLine($"+ [质量]QoS = {e.ApplicationMessage.QualityOfServiceLevel}");

Console.WriteLine($"+ [持久]Retain = {e.ApplicationMessage.Retain}");

Console.WriteLine();

};

        client.Connected += async (s, e) =>
{
Console.WriteLine("### 成功连接MQTT ###");
if (!subscribe.Equals("#")) return;
await client.SubscribeAsync(new TopicFilterBuilder().WithTopic("#").Build());
Console.WriteLine($"### 成功订阅主题[{subscribe}] ###");
}; client.Disconnected += async (s, e) =>
{
Console.WriteLine("### 连接丢失 ###");
await Task.Delay(TimeSpan.FromSeconds(5));
try
{
await client.ConnectAsync(clientOptions);
}
catch
{
Console.WriteLine("### 连接错误 ###");
}
};
} /// <summary>
/// 尝试Client连接到EMQTT
/// </summary>
/// <param name="client">IMqttClient客户端</param>
/// <param name="clientOptions">MqttClientOptions配置选项</param>
public static void TryConnectionAsync(IMqttClient client, MqttClientOptions clientOptions)
{
try
{
client.ConnectAsync(clientOptions).Wait();
}
catch (Exception exception)
{
Console.WriteLine("### 连接错误 ###" + Environment.NewLine + exception);
}
}
}

复制代码

配置三个客户端,一个作为发布者,两个作为订阅者,通过发布者输入任意数据,运行结果如下:

其中发布者客户端会收到一个Retain=True的消息,是因为之前有发布过一条持久化的消息,该消息已经存储在EMQTT中,每次启动均会主动向订阅过"/World"的订阅者再次推送该条持久化的消息。

根据生产消费的机制,此处消息理当已经被消费和清除,但不清楚为何EMQ仍然存在。

总结

本篇简单介绍使用EMQTT的PubSub模式,并使用MQTTnet客户端连接并订阅和发布消息内容。

EMQ (Erlang/Enterprise/Elastic MQTT Broker)的更多相关文章

  1. MQTT的学习研究(二)moquette-mqtt 的使用之mqtt broker的启动

    在MQTT 官网 (http://mqtt.org/software)中有众多MQTT的实现方式.具体参看官网,Moquette是基于Apache Mina 的模型的一个Java MQTT broke ...

  2. MQTT协议 - arduino ESP32 通过精灵一号 MQTT Broker 进行通讯的代码详解

    前言 之前研究了一段时间的 COAP 协议结果爱智那边没有测试工具,然后 arduino 也没有找到合适的库,我懒癌发作也懒得修这库,就只能非常尴尬先暂时放一放了.不过我在 爱智APP -> 设 ...

  3. EMQ、Websocket、MQTT

    mqtt.fx的安装和使用 https://blog.csdn.net/nicholaszao/article/details/79211965 EMO 使用说明 http://emqtt.com/d ...

  4. 移植 MQTT broker mosquitto 到 omapl138

    概述 本次移植使用创龙的 TL138-EVM 开发板,基于 TI 的 MCSDK 开发环境.具体上位机系统为 Ubuntu 12.04-32bit,软件环境基于创龙的用户手册搭建. 为了移植后在 13 ...

  5. 常见MQTT服务器搭建[转载]

    简介 MQTT(Message Queuing Telemetry Transport,消息队列遥测传输)是IBM开发的一个即时通讯协议,它比较适合于在低带宽.不可靠的网络的进行远程传感器和控制设备通 ...

  6. 百万级开源MQTT消息服务器 搭建

    下载地址:http://emqtt.com/downloads 文档地址:http://emqtt.com/docs/v2/index.html 开始使用EMQ 2.0 消息服务器简介EMQ (Erl ...

  7. 常见MQTT服务器搭建与试用

    常见MQTT服务器搭建与试用   简介 MQTT(Message Queuing Telemetry Transport,消息队列遥测传输)是IBM开发的一个即时通讯协议,它比较适合于在低带宽.不可靠 ...

  8. 各种broker对比

    broker的主要职责是接受发布者发布的所有消息,并将其过滤后分发给不同的消息订阅者.如今有很多的broker,下面就是一张关于各种broker对比的图片: 在使用mosquitto时,如果想使用集群 ...

  9. 消息中间件技术 - 浅谈mqtt协议及其实现

    作者:carter(佘虎),转载请注明出处,特别说明:本博文来自博主原博客,为保证新博客中博文的完整性,特复制到此留存,如需转载请注明新博客地址即可. 1.1概念 MQTT(MQ Telemetry ...

随机推荐

  1. redis 学习笔记(二)

    1. 在centos下安装g++,如果输入 yum install g++,那么将会提示找不到g++.因为在centos下g++安装包名字叫做:gcc-c++ 所以应该输入 yum install g ...

  2. Microsoft.VisualStudio.Web.PageInspector.Loader

    未能加载文件或程序集"Microsoft.VisualStudio.Web.PageInspector.Loader, Version=1.0.0.0, Culture=neutral, P ...

  3. React Native常用组件之TabBarIOS、TabBarIOS.Item组件、Navigator组件、NavigatorIOS组件、React Navigation第三方

    以下内容为老版本React Native,faceBook已经有了新的导航组件,请移步其他博客参考>>[我是传送门] 参考资料:React Navigation  react-native ...

  4. session/token/cookie/socket区别

    Session:在计算机中,尤其是在网络应用中,称为“会话控制”.Session 对象存储特定用户会话所需的属性及配置信息.这样,当用户在应用程序的 Web 页之间跳转时,存储在 Session 对象 ...

  5. 混合开发的大趋势之 一个Android程序员眼中的 React.js 箭头函数,const, PropTypes

    转载请注明出处:王亟亟的大牛之路 昨天写了篇React.js的开头之作,讲了讲块级作用域和let,先安利:https://github.com/ddwhan0123/Useful-Open-Sourc ...

  6. redhat 6.8 配置yum源

    一般安装好redhat后,不能注册的话,不能使用系统自带的yum源.但是我们可以自己配置yum源来解决这一问题.下面介绍下redhat配置163yum源. 1. 检查是否安装yum包 rpm -qa ...

  7. Oracle索引以及索引碎片

    索引,可以增加查询速度,若没有索引,每次查询都必须是全表查询.例如,搜索某个记录时(如name="gdpuzxs")时,需要全表扫描一下,因为不知道有多少个name="g ...

  8. java-给微信推送消息 利用企业微信

    目的:给关注用户推送消息 场景:自动化测试,运维监控,接口访问等报错预警.例如线上接口报错,发送提醒消息 准备工作: 1:注册企业号(为什么不用公众号呢?) 企业号注册 2:常用参数介绍: 1:COR ...

  9. Java基础16:Java多线程基础最全总结

    Java基础16:Java多线程基础最全总结 Java中的线程 Java之父对线程的定义是: 线程是一个独立执行的调用序列,同一个进程的线程在同一时刻共享一些系统资源(比如文件句柄等)也能访问同一个进 ...

  10. xcrun: error: active developer path (/Users/XJW/Desktop/Xcode.app/Contents/Developer) does not exist, use `xcode-select --switch path/to/Xcode.app` to

    问题: 装了双xcode     删掉低版本  (注意:低版本xcode 开启过项目 )  创建git时报错 解决方法: sudo xcode-select -switch /Applications ...