热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

gomqtt(嵌入式arm设备)接入物联网平台

gomqtt(嵌入式arm设备)接入物联网平台,Go语言社区,Golang程序员人脉社

#1、设备
任意能跑linux的设备。
当前设备:imx6 内存>=128m 容量>=128m
#2、平台
华为云平台
设备接入服务,开发者中心
#3、设备注册
##1、添加产品
在这里插入图片描述选择添加自定义产品
在这里插入图片描述
##2、添加profile定义,插件
在这里插入图片描述
在这里插入图片描述#4、注册设备
在这里插入图片描述用官方工具计算出clientid等等连接参数
在这里插入图片描述#5、编写代码
##5.1、主函数

// main
package main

import (
	"fmt"
	"sync"

	"time"

	"./user_mqtt"
	//"./user_nanomsg"
	"./utils"
	mqtt "github.com/eclipse/paho.mqtt.golang"
)

type ConfigRead struct {
	sslUrl   string //
	clientId string
	userName string
	passWord string
	pemAdd   string //证书地址

	pubAdd string
	subAdd string
}

//初始化一些变量
var readMsg ConfigRead
//var internalCommunication user_nanomsg.Nanomsg = new(user_nanomsg.NanomsgOptions)
var device1 user_mqtt.DeviceMsg = new(user_mqtt.DeviceMsgOptions)

//var handler *user_nanomsg.NanomsgOptions
func onReceived(client mqtt.Client, message mqtt.Message) {
	fmt.Printf("Receive topic: %s,  payload: %x n", message.Topic(), string(message.Payload()))
	//internalCommunication.PairSocketSend([]byte(message.Payload()))
}

// pub客户端与服务端断连后,触发重连机制
func onPubConnectionLost(client mqtt.Client, err error) {
	fmt.Println("on pub connect lost, try to reconnect")
	user_mqtt.LoopConnect(client)
	client.Subscribe(readMsg.subAdd, 0, onReceived)
}

//读取INI配置文件
func InitConfigRead(o *ConfigRead) bool {
	ini_parser := utils.IniParser{}
	conf_file_name := "/my-demo/mqtt/init.ini"
	if err := ini_parser.Load(conf_file_name); err != nil {
		conf_file_name = "./init.ini"
		if err := ini_parser.Load(conf_file_name); err != nil {
			//fmt.Printf("try load config file[%s] error[%s]n", conf_file_name, err.Error())
			return false
		}
		//return
	}

	o.sslUrl = ini_parser.GetString("connect_sect", "SslUrl")
	o.clientId = ini_parser.GetString("connect_sect", "ClientId")
	o.userName = ini_parser.GetString("connect_sect", "UserName")
	o.passWord = ini_parser.GetString("connect_sect", "PassWord")
	o.pemAdd = ini_parser.GetString("pem_sect", "Pemaddr")

	o.pubAdd = "/huawei/v1/devices/" + readMsg.userName + "/data/binary"
	o.subAdd = "/huawei/v1/devices/" + readMsg.userName + "/command/binary"
	return true
}

//初始化外部通信
func InitMQTTCommunication() bool {
	var ret bool

	if ret = device1.GetPemTlsConfig(readMsg.pemAdd); ret == false {
		fmt.Println("GetPemTlsConfig is error")
		return false
	}

	device1.SettingConnectMsg(readMsg.sslUrl, readMsg.clientId, readMsg.userName, readMsg.passWord)

	device1.SettingPubaddr(readMsg.pubAdd)
	device1.SettingSubaddr(readMsg.subAdd)

	device1.SettingLostCallback(onPubConnectionLost)
	device1.SettingRecCallback(onReceived)

	if ret = device1.StartConnect(); ret == false {
		fmt.Println("StartConnect is error")
		return false
	}

	return true
}

func main() {

	//初始化配置项
	if InitConfigRead(&readMsg) == false {
		fmt.Println("InitConfigRead is error!")
		return
	}

	if InitMQTTCommunication() == false {
		fmt.Println("InitMQTTCommunication is error!!")
		return
	}

	wait := sync.WaitGroup{}
	wait.Add(1)

	pubmsg := []byte{0x00, 0x01}

	go func() {
		for {
			time.Sleep(10 * time.Second)
			device1.PublishMsg(pubmsg)
			//fmt.Println("PublishMsg:%x!!", pubmsg)
		}
	}()

	wait.Wait()
}

##5.2、连接模块代码

package user_mqtt

import (
	"crypto/tls"
	"crypto/x509"
	"io/ioutil"
	"time"

	"fmt"
	//"sync"

	mqtt "github.com/eclipse/paho.mqtt.golang"
)

type DeviceMsg interface {
	GetPemTlsConfig(string) bool                      //获取pem加密
	SettingConnectMsg(string, string, string, string) //设置连接的参数
	SettingPubaddr(string)
	SettingSubaddr(string)
	SettingLostCallback(func(mqtt.Client, error))
	SettingRecCallback(func(mqtt.Client, mqtt.Message))

	StartConnect() bool
	PublishMsg(interface{}) bool                      //上报数据到发布的地址
}

type DeviceMsgOptions struct {
	sslUrl   string //
	clientId string
	userName string
	passWord string

	pubAdd string
	subAdd string

	pemAdd string //证书地址

	Tlsconfig    *tls.Config
	Mqtthandler  mqtt.Client
	LostCallback func(mqtt.Client, error)
	RecCallback  func(mqtt.Client, mqtt.Message)
}

//获取pem加密
func (o *DeviceMsgOptions) GetPemTlsConfig(filename string) bool {
	o.pemAdd = filename
	caCert, err := ioutil.ReadFile(o.pemAdd)
	if err != nil {
		return false
	}
	caCertPool := x509.NewCertPool()
	caCertPool.AppendCertsFromPEM(caCert)

	// Create the TLS Config with the CA pool and enable Client certificate validation
	tlsConfig := &tls.Config{
		ClientCAs:  caCertPool,
		ClientAuth: tls.RequireAndVerifyClientCert,
		// 单向认证,client不校验服务端证书
		InsecureSkipVerify: true,
	}
	o.TlscOnfig= tlsConfig
	return true
}

//设置连接需要的参数
func (o *DeviceMsgOptions) SettingConnectMsg(sslurl string, clientId string, userName string, passWord string) {
	o.sslUrl = sslurl
	o.clientId = clientId
	o.userName = userName
	o.passWord = passWord
}

//上报数据到订阅的地址
func (o *DeviceMsgOptions) PublishMsg(payload interface{}) bool {

	if len(o.pubAdd) == 0 {
		return false
	}

	o.Mqtthandler.Publish(o.pubAdd, 0, false, payload)
	return true
}

//设置发布的地址
func (o *DeviceMsgOptions) SettingPubaddr(pubadd string) {
	o.pubAdd = pubadd
}

//设置订阅的地址的地址
func (o *DeviceMsgOptions) SettingSubaddr(subadd string) {
	o.subAdd = subadd
}

//设置断开触发的程序
func (o *DeviceMsgOptions) SettingLostCallback(callback func(mqtt.Client, error)) {
	o.LostCallback = callback
}

//设置接收触发的程序
func (o *DeviceMsgOptions) SettingRecCallback(callback func(mqtt.Client, mqtt.Message)) {
	o.RecCallback = callback
}

//初始化服务器
func (o *DeviceMsgOptions) StartConnect() bool {
	if len(o.sslUrl) == 0 || len(o.clientId) == 0 || len(o.userName) == 0 || len(o.passWord) == 0 {
		return false
	}
	opts := mqtt.NewClientOptions().AddBroker(o.sslUrl)
	opts.SetClientID(o.clientId)
	opts.SetUsername(o.userName)
	opts.SetPassword(o.passWord)
	opts.SetProtocolVersion(4)

	if len(o.pemAdd) == 0 {
		return false
	}

	opts.SetTLSConfig(o.Tlsconfig)

	opts.OnConnect= onConnect
	opts.AutoRecOnnect= false
	// 回调函数,客户端与服务端断连后立刻被触发
	opts.OnConnectionLost= o.LostCallback
	o.Mqtthandler = mqtt.NewClient(opts)
	LoopConnect(o.Mqtthandler)

	o.Mqtthandler.Subscribe(o.subAdd, 0, o.RecCallback)
	return true
}

//连接成功调用
func onConnect(client mqtt.Client) {
	fmt.Println("on connect")
}

//检查是否连接
func CheckClientToken(token mqtt.Token) (bool, error) {
	if token.Wait() && token.Error() != nil {
		return false, token.Error()
	}
	return true, nil
}

//断开立即调用
func LoopConnect(client mqtt.Client) {
	for {
		token := client.Connect()
		if rs, err := CheckClientToken(token); !rs {
			fmt.Printf("connect error: %sn", err.Error())
		} else {
			break
		}
		time.Sleep(1 * time.Second)
	}
}

##5.3、配置文件读取代码

package utils

import (
    "gopkg.in/ini.v1"
)

type IniParser struct {
    conf_reader *ini.File // config reader
}

type IniParserError struct {
    error_info string
}

func (e *IniParserError) Error() string { return e.error_info }

func (this *IniParser) Load(config_file_name string) error {
    conf, err := ini.Load(config_file_name)
    if err != nil {
        this.conf_reader = nil
        return err
    }
    this.conf_reader = conf
    return nil
}

func (this *IniParser) GetString(section string, key string) string {
    if this.conf_reader == nil {
        return ""
    }

    s := this.conf_reader.Section(section)
    if s == nil {
        return ""
    }

    return s.Key(key).String()
}

func (this *IniParser) GetInt32(section string, key string) int32 {
    if this.conf_reader == nil {
        return 0
    }

    s := this.conf_reader.Section(section)
    if s == nil {
        return 0
    }

    value_int, _ := s.Key(key).Int()

    return int32(value_int)
}

func (this *IniParser) GetUint32(section string, key string) uint32 {
    if this.conf_reader == nil {
        return 0
    }

    s := this.conf_reader.Section(section)
    if s == nil {
        return 0
    }

    value_int, _ := s.Key(key).Uint()

    return uint32(value_int)
}

func (this *IniParser) GetInt64(section string, key string) int64 {
    if this.conf_reader == nil {
        return 0
    }

    s := this.conf_reader.Section(section)
    if s == nil {
        return 0
    }

    value_int, _ := s.Key(key).Int64()
    return value_int
}

func (this *IniParser) GetUint64(section string, key string) uint64 {
    if this.conf_reader == nil {
        return 0
    }

    s := this.conf_reader.Section(section)
    if s == nil {
        return 0
    }

    value_int, _ := s.Key(key).Uint64()
    return value_int
}

func (this *IniParser) GetFloat32(section string, key string) float32 {
    if this.conf_reader == nil {
        return 0
    }

    s := this.conf_reader.Section(section)
    if s == nil {
        return 0
    }

    value_float, _ := s.Key(key).Float64()
    return float32(value_float)
}

func (this *IniParser) GetFloat64(section string, key string) float64 {
    if this.conf_reader == nil {
        return 0
    }

    s := this.conf_reader.Section(section)
    if s == nil {
        return 0
    }

    value_float, _ := s.Key(key).Float64()
    return value_float
}

#6、运行代码
上线成功
上传数据成功
#7、交叉编译
gox -os “linux” -arch arm
传到开发板上运行


推荐阅读
  • Go GUIlxn/walk 学习3.菜单栏和工具栏的具体实现
    本文介绍了使用Go语言的GUI库lxn/walk实现菜单栏和工具栏的具体方法,包括消息窗口的产生、文件放置动作响应和提示框的应用。部分代码来自上一篇博客和lxn/walk官方示例。文章提供了学习GUI开发的实际案例和代码示例。 ... [详细]
  • GPT-3发布,动动手指就能自动生成代码的神器来了!
    近日,OpenAI发布了最新的NLP模型GPT-3,该模型在GitHub趋势榜上名列前茅。GPT-3使用的数据集容量达到45TB,参数个数高达1750亿,训练好的模型需要700G的硬盘空间来存储。一位开发者根据GPT-3模型上线了一个名为debuid的网站,用户只需用英语描述需求,前端代码就能自动生成。这个神奇的功能让许多程序员感到惊讶。去年,OpenAI在与世界冠军OG战队的表演赛中展示了他们的强化学习模型,在限定条件下以2:0完胜人类冠军。 ... [详细]
  • 恶意软件分析的最佳编程语言及其应用
    本文介绍了学习恶意软件分析和逆向工程领域时最适合的编程语言,并重点讨论了Python的优点。Python是一种解释型、多用途的语言,具有可读性高、可快速开发、易于学习的特点。作者分享了在本地恶意软件分析中使用Python的经验,包括快速复制恶意软件组件以更好地理解其工作。此外,作者还提到了Python的跨平台优势,使得在不同操作系统上运行代码变得更加方便。 ... [详细]
  • 初探PLC 的ST 语言转换成C++ 的方法
    自动控制软件绕不开ST(StructureText)语言。它是IEC61131-3标准中唯一的一个高级语言。目前,大多数PLC产品支持ST ... [详细]
  • 问题描述:域名已经备案,我全部都有,也在后台配置了,但是手机预览,还是请求失败,PC端是可以请求 ... [详细]
  • 基于Springboot实现Mqtt
    转载:基于Springboot实现MqttJava端开发:pom.xml: ... [详细]
  • android,mqtt, ... [详细]
  • 2016 linux发行版排行_灵越7590 安装 linux (manjarognome)
    RT之前做了一次灵越7590黑苹果炒作业的文章,希望能够分享给更多不想折腾的人。kawauso:教你如何给灵越7590黑苹果抄作业​zhuanlan.z ... [详细]
  • Java编程实现邻接矩阵表示稠密图的方法及实现类介绍
    本文介绍了Java编程如何实现邻接矩阵表示稠密图的方法,通过一个名为AMWGraph.java的类来构造邻接矩阵表示的图,并提供了插入结点、插入边、获取邻接结点等功能。通过使用二维数组来表示结点之间的关系,并通过元素的值来表示权值的大小,实现了稠密图的表示和操作。对于对稠密图的表示和操作感兴趣的读者可以参考本文。 ... [详细]
  • 如何使用Python从工程图图像中提取底部的方法?
    本文介绍了使用Python从工程图图像中提取底部的方法。首先将输入图片转换为灰度图像,并进行高斯模糊和阈值处理。然后通过填充潜在的轮廓以及使用轮廓逼近和矩形核进行过滤,去除非矩形轮廓。最后通过查找轮廓并使用轮廓近似、宽高比和轮廓区域进行过滤,隔离所需的底部轮廓,并使用Numpy切片提取底部模板部分。 ... [详细]
  • 深入理解Java虚拟机的并发编程与性能优化
    本文主要介绍了Java内存模型与线程的相关概念,探讨了并发编程在服务端应用中的重要性。同时,介绍了Java语言和虚拟机提供的工具,帮助开发人员处理并发方面的问题,提高程序的并发能力和性能优化。文章指出,充分利用计算机处理器的能力和协调线程之间的并发操作是提高服务端程序性能的关键。 ... [详细]
  • 【重识云原生】第四章云网络4.8.3.2节——Open vSwitch工作原理详解
    2OpenvSwitch架构2.1OVS整体架构ovs-vswitchd:守护程序,实现交换功能,和Linux内核兼容模块一起,实现基于流的交换flow-basedswitchin ... [详细]
  • linux进阶50——无锁CAS
    1.概念比较并交换(compareandswap,CAS),是原⼦操作的⼀种,可⽤于在多线程编程中实现不被打断的数据交换操作࿰ ... [详细]
  • 阿里云官方提供的 DEMO里面没有Python接入 阿里云物联网平台(原物联网套件) 的例子,不便于我们在电脑端做虚拟终端的相关测试,本文介绍一种基于使用Python3、MQTT-TCP连接通信 ... [详细]
  • Qt编写物联网管理平台32表格数据
    一、前言用表格来展示采集到的数据,是很多组态系统中最常见的方法,一个表格能够展示的数据特别多,在本系统中,默认做的也是通过表格的形式来展示数据,目前是将所有的设备放在一个表格中, ... [详细]
author-avatar
1212
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有