当前位置: 首页 > news >正文

Unity实现MQTT服务器

首先下载MqttNet:MqttNet下载地址

解压好后使用vs打开,并生成.dll文件(我这里下载的是4.1.2.350版本)

然后再/Source/MQTTnet/bin/Debug/net452 文件夹中找到生成的文件

新建unity工程,创建Plugins文件夹,将文件复制到该文件夹内

然后新建脚本MyMqttServer,代码内带有注释

using MQTTnet.Adapter;
using MQTTnet.Server;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using MQTTnet;
using System.Threading.Tasks;
using System;
using System.Diagnostics.Tracing;
using System.Net;
using MQTTnet.Diagnostics;
using System.Text;
using MQTTnet.Protocol;
using static UnityEditor.ObjectChangeEventStream;namespace MQTT.Server
{/// <summary>/// 客户端信息/// </summary>public class MqttClientObject{public MqttClientObject(string clientID, string userName = "", string password = ""){this.ClientID = clientID;this.UserName = userName;this.PassWord = password;}public string ClientID { get; set; }public string UserName { get; set; }public string PassWord { get; set; }}/// <summary>/// MQTT服务/// </summary>public class MyMqttServer{/// <summary>/// 服务器对象/// </summary>private MqttServer m_MqttServer = null;/// <summary>/// Mqtt服务器选项生成器/// </summary>MqttServerOptionsBuilder optionbuilder = null;/// <summary>/// 连接的客户端/// </summary>private List<MqttClientObject> m_MqttClientObject = new List<MqttClientObject>();/// <summary>/// 开启服务器/// </summary>/// <param name="port"></param>public void StartMqttServer(int port = 1883){//1.创建服务器对象if (m_MqttServer == null){//创建Mqtt服务器选项生成器optionbuilder = new MqttFactory().CreateServerOptionsBuilder();//设置带有默认终端optionbuilder.WithDefaultEndpoint();//设置终端端口号optionbuilder.WithDefaultEndpointPort(port);//设置具有持续会话optionbuilder.WithPersistentSessions(true);//设置无默认通信超时optionbuilder.WithDefaultCommunicationTimeout(TimeSpan.FromMilliseconds(60000));m_MqttServer = new MqttFactory().CreateMqttServer(optionbuilder.Build());}//监测服务器 开启/关闭m_MqttServer.StartedAsync += ServerStarted;m_MqttServer.StoppedAsync += ServerStoped;//监测客户端 连接/断开连接m_MqttServer.ClientConnectedAsync += ClientConnected;m_MqttServer.ClientDisconnectedAsync += ClientDisconnected;//监测客户端 订阅/取消订阅m_MqttServer.ClientSubscribedTopicAsync += ClientSubscribedTopic;m_MqttServer.ClientUnsubscribedTopicAsync += ClientUnSubscribedTopic;//客户端连接信息验证m_MqttServer.ValidatingConnectionAsync += ValidatingConnection;//获取客户端发送的消息m_MqttServer.InterceptingPublishAsync += InterceptingPublish;//开启服务器m_MqttServer.StartAsync();}/// <summary>/// 关闭服务/// </summary>public void StopMqttServer(){if (m_MqttServer != null){m_MqttServer.StopAsync();}}/// <summary>/// 获取服务器状态--开启/关闭/// </summary>/// <returns></returns>public bool GetMqttServerState(){if (m_MqttServer == null){return false;}return m_MqttServer.IsStarted;}/// <summary>/// 服务器完成开启/// </summary>/// <param name="eventArgs"></param>/// <returns></returns>/// <exception cref="NotImplementedException"></exception>private Task ServerStarted(EventArgs eventArgs){Debug.Log("服务: started!");return Task.CompletedTask;}/// <summary>/// 服务器完成关闭/// </summary>/// <param name="eventArgs"></param>/// <returns></returns>/// <exception cref="NotImplementedException"></exception>private Task ServerStoped(EventArgs eventArgs){Debug.Log("服务: stoped!");return Task.CompletedTask;}/// <summary>/// 客户端连接完成/// </summary>/// <param name="eventArgs"></param>/// <returns></returns>/// <exception cref="NotImplementedException"></exception>private Task ClientConnected(ClientConnectedEventArgs eventArgs){Debug.Log($"服务:client Connected ClientId:{eventArgs.ClientId}");m_MqttClientObject.Add(new MqttClientObject(eventArgs.ClientId, eventArgs.UserName));return Task.CompletedTask;}/// <summary>/// 客户端订阅主题完成/// </summary>/// <param name="eventArgs"></param>/// <returns></returns>/// <exception cref="NotImplementedException"></exception>private Task ClientSubscribedTopic(ClientSubscribedTopicEventArgs eventArgs){Debug.Log($"Client:{eventArgs.ClientId} -- Subscribed -- Topic:{eventArgs.TopicFilter.Topic}");ServerPublich(eventArgs.TopicFilter.Topic, $"Client:{eventArgs.ClientId} Subscribed this Topic");return Task.CompletedTask;}/// <summary>/// 客户端取消订阅主题完成/// </summary>/// <param name="eventArgs"></param>/// <returns></returns>/// <exception cref="NotImplementedException"></exception>private Task ClientUnSubscribedTopic(ClientUnsubscribedTopicEventArgs eventArgs){Debug.Log($"Client:{eventArgs.ClientId} -- Subscribed -- Topic:{eventArgs.TopicFilter}");return Task.CompletedTask;}/// <summary>/// 客户端断开连接完成/// </summary>/// <param name="eventArgs"></param>/// <returns></returns>/// <exception cref="NotImplementedException"></exception>private Task ClientDisconnected(ClientDisconnectedEventArgs eventArgs){Debug.Log($"Client:client DisConnected ClientId:{eventArgs.ClientId}");return Task.CompletedTask;}/// <summary>/// 客户端连接信息验证/// </summary>/// <param name="args"></param>/// <returns></returns>private Task ValidatingConnection(ValidatingConnectionEventArgs args){Debug.Log($"UserName:{args.UserName},PassWord:{args.Password}");return Task.CompletedTask;}/// <summary>/// 获取客户端发送的消息/// </summary>/// <param name="args"></param>/// <returns></returns>private Task InterceptingPublish(InterceptingPublishEventArgs args){Debug.Log($"Client:{args.ClientId} send Message : {Encoding.UTF8.GetString(args.ApplicationMessage.Payload)} -- Topic:{args.ApplicationMessage.Topic}");return Task.CompletedTask;}/// <summary>/// 服务器广播消息/// </summary>/// <param name="topic">主题</param>/// <param name="message">信息</param>public void ServerPublich(string topic, string message, bool isRetain = false, MqttQualityOfServiceLevel level = MqttQualityOfServiceLevel.ExactlyOnce){var builder = new MqttApplicationMessageBuilder().WithTopic(topic).WithPayload(message).WithRetainFlag(isRetain).WithQualityOfServiceLevel(level).Build();var data = new InjectedMqttApplicationMessage(builder);data.SenderClientId = "1";m_MqttServer.InjectApplicationMessage(data);}}
}

创建脚本MyMqttClient,代码内带有注释

using MQTTnet;
using MQTTnet.Client;
using MQTTnet.Diagnostics;
using MQTTnet.Protocol;
using MQTTnet.Server;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;/// <summary>
/// MQTT客户端
/// </summary>
public class MyMqttClient
{private IMqttClient m_MqttClient = null;private string m_ClientID;/// <summary>/// 创建客户端并连接服务器/// </summary>/// <param name="clientID"></param>/// <param name="ip"></param>/// <param name="port"></param>public MyMqttClient(string clientID, string ip = "127.0.0.1", int port = 1883){m_ClientID = clientID;//客户端选项生成器var options = new MqttClientOptionsBuilder().WithClientId(m_ClientID).WithTcpServer(ip, port).Build();//创建客户端m_MqttClient = new MqttFactory().CreateMqttClient();//监测客户端 连接/断开连接 完成m_MqttClient.ConnectedAsync += ClientConnected;m_MqttClient.DisconnectedAsync += ClientDisConnected;//客户端接收到消息m_MqttClient.ApplicationMessageReceivedAsync += ReceiveMsg;//连接服务器m_MqttClient.ConnectAsync(options);}/// <summary>/// 接收到消息/// </summary>/// <param name="args"></param>/// <returns></returns>private Task ReceiveMsg(MqttApplicationMessageReceivedEventArgs args){Debug.Log($"Receive Message From Client:{args.ClientId} msg:{Encoding.UTF8.GetString(args.ApplicationMessage.Payload)}");return Task.CompletedTask;}/// <summary>/// 断开连接完成/// </summary>/// <param name="args"></param>/// <returns></returns>private Task ClientDisConnected(MqttClientDisconnectedEventArgs args){Debug.Log("disConnected");return Task.CompletedTask;}/// <summary>/// 连接完成/// </summary>/// <param name="args"></param>/// <returns></returns>private Task ClientConnected(MqttClientConnectedEventArgs args){Debug.Log("connected");return Task.CompletedTask;}/// <summary>/// 发布消息/// </summary>public void PublishMsg(string topic, string message, MqttQualityOfServiceLevel level = MqttQualityOfServiceLevel.ExactlyOnce, bool isRetain = false){m_MqttClient.PublishStringAsync(topic, message, level, isRetain);}/// <summary>/// 订阅主题/// </summary>public void Subscribe(string topic){m_MqttClient.SubscribeAsync(new MqttTopicFilterBuilder().WithTopic(topic).Build());}
}

到这服务器与客户端脚本完成,接下来只需要写一些测试脚本,调用上面脚本的接口,即可完成服务器的开启/关闭,客户端连接,收发消息等功能。

相关文章:

Unity实现MQTT服务器

首先下载MqttNet&#xff1a;MqttNet下载地址 解压好后使用vs打开&#xff0c;并生成.dll文件&#xff08;我这里下载的是4.1.2.350版本&#xff09; 然后再/Source/MQTTnet/bin/Debug/net452 文件夹中找到生成的文件 新建unity工程&#xff0c;创建Plugins文件夹&#xff0…...

Linux(centos) 下 Mysql 环境安装

linux 下进行环境安装相对比较简单&#xff0c;可还是会遇到各种奇奇怪怪的问题&#xff0c;我们来梳理一波 安装 mysql 我们会用到下地址&#xff1a; Mysql 官方文档的地址&#xff0c;可以参考&#xff0c;不要全部使用 https://dev.mysql.com/doc/refman/8.0/en/linux-i…...

决策树(Decision Tree)

决策树的定义: 分类决策树模型是一种描述对实例进行分类的树形结构。决策树由结点&#xff08;node&#xff09;和有向边&#xff08;directed edge&#xff09;组成。结点有两种类型: 内部结点&#xff08;internal node&#xff09;和叶结点&#xff08;leaf node&#xff0…...

解决 PaddleClas 下载预训练模型报错 ModuleNotFoundError No module named ‘ppcls‘ 的问题

当我们在使用 PaddleClas 进行预训练模型下载时&#xff0c;可能会遇到一个报错&#xff0c;报错信息为 ModuleNotFoundError: No module named ppcls。这个错误通常是因为 Python 解释器无法找到名为 ppcls 的模块&#xff0c;而我们的代码中正尝试导入它。让我们一起来解决这…...

视觉化洞察:为什么我们需要数据可视化?

为什么我们需要数据可视化&#xff1f;这个问题在信息时代变得愈发重要。数据&#xff0c;如今已成为生活的一部分&#xff0c;我们每天都在产生大量的数据&#xff0c;从社交媒体到购物记录&#xff0c;从健康数据到工作表现&#xff0c;数据无处不在。然而&#xff0c;数据本…...

C语言函数概述——拜佛代码

函数是一种可重用的代码块&#xff0c;用于执行特定任务或完成特定功能函数作用&#xff1a;对具备相同逻辑的代码进行封装&#xff0c;提高代码的编写效率&#xff0c;实现对代码的重用函数作用演示代码&#xff1a; #include <stdio.h>// 定义函数 void func() {print…...

防火墙日志分析工具

防火墙提供对进入组织网络的网络流量的来源和类型的可见性&#xff0c;这使得防火墙日志成为重要的信息源&#xff0c;包括所有连接的源地址、目标地址、协议和端口号等详细信息&#xff0c;此信息可以提供对未知安全威胁的见解&#xff0c;是威胁管理中的重要工具。 防火墙日…...

Autofac中多个类继承同一个接口,如何注入?与抽象工厂模式相结合

多个类继承同一个接口,如何注入&#xff1f;与抽象工厂模式相结合 需求: 原来是抽象工厂模式,多个类继承同一个接口。 现在需要使用Autofac进行选择性注入。 Autofac默认常识: Autofac中多个类继承同一个接口,默认是最后一个接口注入的类。 解决方案&#xff1a;(约定大于配…...

Django系列之日志配置

如何配置 settings.py 文件中增加如下日志模块 """logger 配置""" LOGGING {version: 1,disable_existing_loggers: False, # 是否去掉目前项目中其他地方中以及使用的日志功能&#xff0c;但是将来我们可能会引入第三方的模块&#xff0c;里…...

四轴飞行器传感器(SimulinkMatlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…...

学习 使用pandas库 DataFrame 使用

1 、 数据排序 sort_values()函数 by:要排序的名称或名称列表&#xff0c; sorted_df df.sort_values(byAge,ascendingFalse) 由大到小排序&#xff1b; sorted_df df.sort_values(byAge) 由小到大排序&#xff1b; # 创建一个示例数据帧 data {Name: [Tom, Nick, John…...

C++字符串详解

C 大大增强了对字符串的支持&#xff0c;除了可以使用C风格的字符串&#xff0c;还可以使用内置的 string 类。string 类处理起字符串来会方便很多&#xff0c;完全可以代替C语言中的字符数组或字符串指针。 string 是 C 中常用的一个类&#xff0c;它非常重要&#xff0c;我们…...

vant2 van-calendar组件增加清除按钮和确定按钮

利用自定义插槽增加一个清除按钮 <van-calendar ref"fTime1" select"selectTimePicker" confirm"changeTimePicker" :default-date"null" :show-confirm"false" v-model"timePickerShow" type"range&quo…...

Spring redis使用报错Read timed out排查解决

文章目录 使用场景报错信息解决方式 使用场景 我们使用redis作为缓存服务&#xff0c;缓存一些业务数据&#xff0c;如路口点位信息、渠化信息、设备信息等有一些需要实时计算的数据&#xff0c;缓存在redis里&#xff0c;如实时信号周期相位、周期内过车数量等有需要不同服务…...

C语言每日一练-------Day(9)

本专栏为c语言练习专栏&#xff0c;适合刚刚学完c语言的初学者。本专栏每天会不定时更新&#xff0c;通过每天练习&#xff0c;进一步对c语言的重难点知识进行更深入的学习。 今日练习题关键字&#xff1a;字符个数统计 多数元素 投票法 &#x1f493;博主csdn个人主页&#xf…...

SpringCloud(十)——ElasticSearch简单了解(三)数据聚合和自动补全

文章目录 1. 数据聚合1.1 聚合介绍1.2 Bucket 聚合1.3 Metrics 聚合1.4 使用 RestClient 进行聚合 2. 自动补全2.1 安装补全包2.2 自定义分词器2.3 自动补全查询2.4 拼音自动补全查询2.5 RestClient 实现自动补全2.5.1 建立索引2.5.2 修改数据定义2.5.3 补全查询2.5.4 解析结果…...

二叉查找树(binary search tree)(难度7)

C数据结构与算法实现&#xff08;目录&#xff09; 答案在此&#xff1a;二叉查找树&#xff08;binary search tree&#xff09;&#xff08;答案&#xff09; 写在前面 部分内容参《算法导论》 基本接口实现 1 删除 删除值为value的第一个节点 删除叶子节点1 删除叶子节…...

windows环境装MailHog

背景&#xff1a;win10系统&#xff0c;windows 宝塔&#xff0c;laravel 项目&#xff0c;邮件相关需要装一个MailHog 下载地址&#xff1a;https://sourceforge.net/projects/mailhog.mirror/ 直接下载&#xff0c;下载后双击运行就可以了&#xff0c;系统可能提示”不信任“…...

Ubuntu 22.04.2 LTS 安装python3.6后报错No module named ‘ufw‘

查明原因&#xff1a; vim /usr/sbin/ufw 初步判断是python版本的问题。 # 查看python3软链接 ll /usr/bin/python3 将python3的软链接从python3.6换成之前的3.10&#xff0c;根据自己电脑情况。 可以查看下 /usr/bin 下有什么 我这是python3.10 所以解决办法是 # 移除py…...

Flutter小功能实现-咖啡店

1 导航栏实现 效果图&#xff1a; 1.Package google_nav_bar: ^5.0.6 使用文档&#xff1a; google_nav_bar | Flutter Package 2.Code //MyBottomNavBar class MyBottomNavBar extends StatelessWidget {void Function(int)? onTabChange;MyBottomNavBar({super.key, …...

挑战杯推荐项目

“人工智能”创意赛 - 智能艺术创作助手&#xff1a;借助大模型技术&#xff0c;开发能根据用户输入的主题、风格等要求&#xff0c;生成绘画、音乐、文学作品等多种形式艺术创作灵感或初稿的应用&#xff0c;帮助艺术家和创意爱好者激发创意、提高创作效率。 ​ - 个性化梦境…...

基于大模型的 UI 自动化系统

基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...

模型参数、模型存储精度、参数与显存

模型参数量衡量单位 M&#xff1a;百万&#xff08;Million&#xff09; B&#xff1a;十亿&#xff08;Billion&#xff09; 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的&#xff0c;但是一个参数所表示多少字节不一定&#xff0c;需要看这个参数以什么…...

在鸿蒙HarmonyOS 5中实现抖音风格的点赞功能

下面我将详细介绍如何使用HarmonyOS SDK在HarmonyOS 5中实现类似抖音的点赞功能&#xff0c;包括动画效果、数据同步和交互优化。 1. 基础点赞功能实现 1.1 创建数据模型 // VideoModel.ets export class VideoModel {id: string "";title: string ""…...

家政维修平台实战20:权限设计

目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系&#xff0c;主要是分成几个表&#xff0c;用户表我们是记录用户的基础信息&#xff0c;包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题&#xff0c;不同的角色&#xf…...

04-初识css

一、css样式引入 1.1.内部样式 <div style"width: 100px;"></div>1.2.外部样式 1.2.1.外部样式1 <style>.aa {width: 100px;} </style> <div class"aa"></div>1.2.2.外部样式2 <!-- rel内表面引入的是style样…...

鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/

使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题&#xff1a;docker pull 失败 网络不同&#xff0c;需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...

如何在网页里填写 PDF 表格?

有时候&#xff0c;你可能希望用户能在你的网站上填写 PDF 表单。然而&#xff0c;这件事并不简单&#xff0c;因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件&#xff0c;但原生并不支持编辑或填写它们。更糟的是&#xff0c;如果你想收集表单数据&#xff…...

使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度

文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...

【分享】推荐一些办公小工具

1、PDF 在线转换 https://smallpdf.com/cn/pdf-tools 推荐理由&#xff1a;大部分的转换软件需要收费&#xff0c;要么功能不齐全&#xff0c;而开会员又用不了几次浪费钱&#xff0c;借用别人的又不安全。 这个网站它不需要登录或下载安装。而且提供的免费功能就能满足日常…...