go语言实现mqtt协议的实践

目录
  • 一、什么是MQTT
  • 二、Go语言MQTT服务器Broker的搭建
  • 三、Go客户端访问简单API

一、什么是MQTT

MQTT(Message Queuing Telemetry Transport,消息队列遥测传输协议),是一种基于发布/订阅(publish/subscribe)模式的“轻量级”通讯协议,该协议构建于TCP/IP协议上,由IBM在1999年发布。

MQTT最大优点在于,可以以极少的代码和有限的带宽,为连接远程设备提供实时可靠的消息服务。作为一种低开销、低带宽占用的即时通讯协议,使其在物联网、小型设备、移动应用等方面有较广泛的应用

MQTT是一个基于客户端-服务器的消息发布/订阅传输协议。MQTT协议是轻量、简单、开放和易于实现的,这些特点使它适用范围非常广泛。在很多情况下,包括受限的环境中,如:机器与机器(M2M)通信和物联网(IoT)。其在,通过卫星链路通信传感器、偶尔拨号的医疗设备、智能家居、及一些小型化设备中已广泛使用

MQTT还有一个特点就是客户端之间不用相互通信, MQTT通信更像是邮箱服务,发布者发布消息到服务器,接收者只要订阅了其服务在线后即可收到

实现MQTT协议需要客户端和服务器端通讯完成,在通讯过程中,MQTT协议中有三种身份:发布者(Publish)、代理(Broker)(服务器)、订阅者(Subscribe)。其中,消息的发布者和订阅者都是客户端,消息代理是服务器,消息发布者可以同时是订阅者。

MQTT传输的消息分为:主题(Topic)和负载(payload)两部分:

(1)Topic,可以理解为消息的类型,订阅者订阅(Subscribe)后,就会收到该主题的消息内容(payload);

(2)payload,可以理解为消息的内容,是指订阅者具体要使用的内容。

Topic就是消息名,payload就是消息体

MQTT会构建底层网络传输:它将建立客户端到服务器的连接,提供两者之间的一个有序的、无损的、基于字节流的双向传输。

当应用数据通过MQTT网络发送时,MQTT会把与之相关的**服务质量(QoS)主题名(Topic)**相关连。

二、Go语言MQTT服务器Broker的搭建

服务端用erlang编写的一个开源项目:emqqtd

# 下载安装包
wget https://github.com/emqx/emqx/releases/download/v4.0.4/emqx-ubuntu18.04-v4.0.4.zip
cd mqttd/emqx
.
├── bin
├── data
├── erts-10.5.2
├── etc
├── lib
├── log
└── releases
# 开启服务
./bin/emqx start
# 查看状态
./bin/emqx_ctl status
# 停止服务
./bin/emqx stop

找到自己的IP,访问http://[你的IP]:18083/#/clients

  • 用户名:admin
  • 密码:public

即可进入服务器的控制台

三、Go客户端访问简单API

客户端用golang客户端的库:“github.com/eclipse/paho.mqtt.golang”

# 下载依赖包
go get -u github.com/eclipse/paho.mqtt.golang

实例如下:

编写了两个函数一个发布一个订阅,传入参数即可服务

修改EMQServerAddress为你服务器的IP

package main

// 与后端mqtt服务交互

import (
	"fmt"
	mqtt "github.com/eclipse/paho.mqtt.golang"
	"log"
	"os"
	"strconv"
	"time"
)

const EMQServerAddress = "你的IP"

// 创建全局mqtt publish消息处理 handler
var messagePubHandler mqtt.MessageHandler = func(client mqtt.Client, msg mqtt.Message) {
	fmt.Println("Push Message:")
	fmt.Printf("TOPIC: %s\n", msg.Topic())
	fmt.Printf("MSG: %s\n", msg.Payload())
}

// 创建全局mqtt sub消息处理 handler
var messageSubHandler mqtt.MessageHandler = func(client mqtt.Client, msg mqtt.Message) {
	fmt.Println("收到订阅消息:")
	fmt.Printf("Sub Client Topic : %s \n", msg.Topic())
	fmt.Printf("Sub Client msg : %s \n", msg.Payload())
}

// 连接的回掉函数
var connectHandler mqtt.OnConnectHandler =func(client mqtt.Client) {
	fmt.Println("新的连接!" + " Connected")
}

// 丢失连接的回掉函数
var connectLostHandler mqtt.ConnectionLostHandler = func(client mqtt.Client, err error) {
	fmt.Printf("Connect loss: %v\n", err)
}

func init() {
	// 配置错误提示
	mqtt.DEBUG = log.New(os.Stdout, "		[mqttDEBUG]", 0)
	mqtt.ERROR = log.New(os.Stdout, " 	[mqttERROR]", 0)
}

/**
 * @Description: 发布订阅
 * @param clientID
 * @param addr
 * @param topic
 * @param payload
 */
func Push(topic string, qos byte, retain bool, payload string) {
	// opts ClientOptions 用于设置 broker,端口,客户端 id ,用户名密码等选项
	opts := mqtt.NewClientOptions().AddBroker("tcp://" + EMQServerAddress + ":1883").SetClientID("test_push")
	opts.SetKeepAlive(60 * time.Second)
	// Message callback handler,在没有任何订阅时,发布端调用此函数
	opts.SetDefaultPublishHandler(messagePubHandler)
	opts.SetPingTimeout(1 * time.Second)
	opts.OnConnect = connectHandler
	opts.OnConnectionLost = connectLostHandler
	client := mqtt.NewClient(opts)
	if token := client.Connect(); token.Wait() && token.Error() != nil {
		panic(token.Error())
	}
	//发布消息
	// qos是服务质量: ==1: 一次, >=1: 至少一次, <=1:最多一次
	// retained: 表示mqtt服务器要保留这次推送的信息,如果有新的订阅者出现,就会把这消息推送给它(持久化推送)
	token := client.Publish(topic, qos, retain, payload)
	token.Wait()
	fmt.Println("Push Data : "+topic, "Data Size is "+strconv.Itoa(len(payload)))
	fmt.Println("Disconnect with broker")
	client.Disconnect(250)
}

/**
 * @Description: 订阅与取消订阅
 * @param clientID
 * @param addr
 * @param topic
 * @param isSub
 */
func Subscription(topic string, qos byte, isSub bool, handleFun func([]byte)) {
	opts := mqtt.NewClientOptions().AddBroker("tcp://" + EMQServerAddress + ":1883").SetClientID("sub_test")
	opts.SetKeepAlive(60 * time.Second)
	opts.SetPingTimeout(1 * time.Second)
	opts.OnConnect = func(client mqtt.Client) {
		fmt.Println("New Subscription! Connected" + " => " + topic)
	}
	opts.OnConnectionLost = connectLostHandler
	client := mqtt.NewClient(opts)
	if token := client.Connect(); token.Wait() && token.Error() != nil {
		panic(token.Error())
	}

	if isSub {
		// 订阅消息
		if token := client.Subscribe(topic, qos, func(client mqtt.Client, msg mqtt.Message) {
			fmt.Printf("Receive Subscribe Message :")
			fmt.Printf("Sub Client Topic : %s, Data size is  %d \n", msg.Topic(), len(msg.Payload()))
			if len(msg.Payload()) > 0 {
				handleFun(msg.Payload())
			}
		}); token.Wait() && token.Error() != nil {
			fmt.Println(token.Error())
			os.Exit(1)
		}
	} else {
		// 取消订阅
		if token := client.Unsubscribe(topic); token.Wait() && token.Error() != nil {
			fmt.Println(token.Error())
			os.Exit(1)
		}
	}
}

学习资料:

https://studygolang.com/articles/14452

https://blog.csdn.net/jacky128256/article/details/105610456

到此这篇关于go语言实现mqtt协议的实践的文章就介绍到这了,更多相关go语言 mqtt协议内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 在Node.js下运用MQTT协议实现即时通讯及离线推送的方法

    前言 前些日子了解到mqtt这样一个协议,可以在web上达到即时通讯的效果,但网上并不能很方便地找到一篇目前版本的在node下正确实现这个协议的博客. 自己捣鼓了一段时间,理解不深刻,但也算是基本能够达到使用目的. 本文尚未对离线消息的接收顺序进行处理. 代码 服务端: server.js //服务端引入中间件mosca let mosca = require('mosca') let settings = { port: 5112 } let server = new mosca.Server

  • 安卓开发之mqtt协议实例代码

    首先物联网协议mqtt协议是基于tcp/ip协议的,使用了官方的mqttclient框架 /* *初始化mqttclient */ private void init() { try { //MQTT的连接设置 options = new MqttConnectOptions(); //host为主机名,test为clientid即连接MQTT的客户端ID,一般以客户端唯一标识符表示,MemoryPersistence设置clientid的保存形式,默认为以内存保存 client = new M

  • go语言实现mqtt协议的实践

    目录 一.什么是MQTT 二.Go语言MQTT服务器Broker的搭建 三.Go客户端访问简单API 一.什么是MQTT MQTT(Message Queuing Telemetry Transport,消息队列遥测传输协议),是一种基于发布/订阅(publish/subscribe)模式的"轻量级"通讯协议,该协议构建于TCP/IP协议上,由IBM在1999年发布. MQTT最大优点在于,可以以极少的代码和有限的带宽,为连接远程设备提供实时可靠的消息服务.作为一种低开销.低带宽占用的

  • 计算机网络编程MQTT协议基础原理详解

    目录 什么是 MQTT 协议 MQTT 基础 发布 - 订阅模式 可拓展性 消息过滤 基于主题的过滤 基于内容的过滤 基于类型的过滤 MQTT 与消息队列的区别 MQTT 重要概念 MQTT client MQTT broker MQTT Connection 消息报文 CONNECT CONNACK 消息类型 发布 订阅 确认消息 退订 确认退订 聊聊 Topic 通配符 单级通配符 多级通配符 之前有位读者给我留言说想要了解一下什么是 MQTT 协议,顺便还把我夸了一把,有点不好意思啦. 那

  • Vue.js项目前端多语言方案的思路与实践

    目录 一.通常有哪些内容需要处理 二.基本思路 三.具体实践中的一些细节 1.获取当前应该采用何种语言的getLang模块的实现 2.Vux组件的多语言包的配置 3.vux-loader的配置 4.自定义组件内外文案的多语言化 5.vuex-i18n的实现 6.图片的多语言化 7.在当前页面通过按钮切换当前语言后,如何更新当前页面的内容? 8.Yaml中特殊字符的转义 总结 前端的国际化是一个比较常见的需求.但网上关于这一方面的直接可用的方案却不多.最近刚做了一版基于Vue.js的多语言实现,在

  • Android开发MQTT协议的模型及通信浅析

    目录 前言 什么是MQTT协议 MQTT协议的模型 开发MQTT通信 1. 处理客户端和服务端 (1)服务端开发 (2)客户端开发 2. 客户端开发 Paho的mqtt的BUG 总结 前言 为什么要讲MQTT协议?因为现在越来越多的领域会使用到这个协议,无论是做M2M,还是做Iot,或是想实现推送功能,MQTT都是一个不错的选择. 什么是MQTT协议 MQTT协议又称为消息队列要测传输协议,他是一种基于发布/订阅范式的消息协议,并且它是一种基于TCP/IP协议族的应用层协议. 可以看出的它的特点

  • 解析C语言基于UDP协议进行Socket编程的要点

    两种协议 TCP 和 UDP 前者可以理解为有保证的连接,后者是追求快速的连接. 当然最后一点有些 太过绝对 ,但是现在不需熬考虑太多,因为初入套接字编程,一切从简. 稍微试想便能够大致理解, TCP 追求的是可靠的传输数据, UDP 追求的则是快速的传输数据. 前者有繁琐的连接过程,后者则是根本不建立可靠连接(不是绝对),只是将数据发送而不考虑是否到达. 以下例子以 *nix 平台的便准为例,因为 Windows平台需要考虑额外的加载问题,稍作添加就能在 Windows 平台上运行UDP. U

  • 深入解析Swift语言中的协议

    协议为方法,属性和其他要求的功能提供了一个蓝本.它只是描述了方法或属性的骨架,而不是实现.方法和属性实现还可以通过定义类,函数和枚举完成.协议的一致性是指方法或属性满足协议的要求. 语法 协议也遵循类似类,结构和枚举的语法: 复制代码 代码如下: protocol SomeProtocol {     // protocol definition } 协议在类,结构或枚举类型命名声明.单个和多个协议的声明也是可以的.如果多个协议规定,它们必须用逗号分隔. 复制代码 代码如下: struct So

  • Go语言中的函数式编程实践

    本文主要讲解Go语言中的函数式编程概念和使用,分享给大家,具体如下: 主要知识点: Go语言对函数式编程的支持主要体现在闭包上面 闭包就是能够读取其他函数内部变量的函数.只有函数内部的子函数才能读取局部变量,所以闭包可以理解成"定义在一个函数内部的函数".在本质上,闭包是将函数内部和函数外部连接起来的桥梁. 学习闭包的基本使用 标准的闭包具有不可变性:不能有状态,只能有常量和函数,而且函数只能有一个参数,但是一般可以不用严格遵守 使用闭包 实现 斐波那契数列 学习理解函数实现接口 使用

  • 易语言注册自定义协议Register protocol

    Register protocol tencent:// thunder:// 是 腾讯 和 迅雷 的协议,即页面上或地址栏里的链接只要输入带有 tencent://- 的协议,就会自动调用一个已写好的程序执行该协议的操作. 或者是打开页面,迅雷的是下载资源的链接. 通过微软的说明,知道这是Register protocol,对于 Windows.Linux 和 OS X 操作系统都可以注册这样的协议.比如说Windows,其实只需写入注册表,即可实现协议与执行程序的关联. DLL命令表 .版本

随机推荐