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:MqttNet下载地址 解压好后使用vs打开,并生成.dll文件(我这里下载的是4.1.2.350版本) 然后再/Source/MQTTnet/bin/Debug/net452 文件夹中找到生成的文件 新建unity工程,创建Plugins文件夹࿰…...
Linux(centos) 下 Mysql 环境安装
linux 下进行环境安装相对比较简单,可还是会遇到各种奇奇怪怪的问题,我们来梳理一波 安装 mysql 我们会用到下地址: Mysql 官方文档的地址,可以参考,不要全部使用 https://dev.mysql.com/doc/refman/8.0/en/linux-i…...
决策树(Decision Tree)
决策树的定义: 分类决策树模型是一种描述对实例进行分类的树形结构。决策树由结点(node)和有向边(directed edge)组成。结点有两种类型: 内部结点(internal node)和叶结点(leaf node࿰…...
解决 PaddleClas 下载预训练模型报错 ModuleNotFoundError No module named ‘ppcls‘ 的问题
当我们在使用 PaddleClas 进行预训练模型下载时,可能会遇到一个报错,报错信息为 ModuleNotFoundError: No module named ppcls。这个错误通常是因为 Python 解释器无法找到名为 ppcls 的模块,而我们的代码中正尝试导入它。让我们一起来解决这…...
视觉化洞察:为什么我们需要数据可视化?
为什么我们需要数据可视化?这个问题在信息时代变得愈发重要。数据,如今已成为生活的一部分,我们每天都在产生大量的数据,从社交媒体到购物记录,从健康数据到工作表现,数据无处不在。然而,数据本…...
C语言函数概述——拜佛代码
函数是一种可重用的代码块,用于执行特定任务或完成特定功能函数作用:对具备相同逻辑的代码进行封装,提高代码的编写效率,实现对代码的重用函数作用演示代码: #include <stdio.h>// 定义函数 void func() {print…...
防火墙日志分析工具
防火墙提供对进入组织网络的网络流量的来源和类型的可见性,这使得防火墙日志成为重要的信息源,包括所有连接的源地址、目标地址、协议和端口号等详细信息,此信息可以提供对未知安全威胁的见解,是威胁管理中的重要工具。 防火墙日…...
Autofac中多个类继承同一个接口,如何注入?与抽象工厂模式相结合
多个类继承同一个接口,如何注入?与抽象工厂模式相结合 需求: 原来是抽象工厂模式,多个类继承同一个接口。 现在需要使用Autofac进行选择性注入。 Autofac默认常识: Autofac中多个类继承同一个接口,默认是最后一个接口注入的类。 解决方案:(约定大于配…...
Django系列之日志配置
如何配置 settings.py 文件中增加如下日志模块 """logger 配置""" LOGGING {version: 1,disable_existing_loggers: False, # 是否去掉目前项目中其他地方中以及使用的日志功能,但是将来我们可能会引入第三方的模块,里…...
四轴飞行器传感器(SimulinkMatlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...
学习 使用pandas库 DataFrame 使用
1 、 数据排序 sort_values()函数 by:要排序的名称或名称列表, sorted_df df.sort_values(byAge,ascendingFalse) 由大到小排序; sorted_df df.sort_values(byAge) 由小到大排序; # 创建一个示例数据帧 data {Name: [Tom, Nick, John…...
C++字符串详解
C 大大增强了对字符串的支持,除了可以使用C风格的字符串,还可以使用内置的 string 类。string 类处理起字符串来会方便很多,完全可以代替C语言中的字符数组或字符串指针。 string 是 C 中常用的一个类,它非常重要,我们…...
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作为缓存服务,缓存一些业务数据,如路口点位信息、渠化信息、设备信息等有一些需要实时计算的数据,缓存在redis里,如实时信号周期相位、周期内过车数量等有需要不同服务…...
C语言每日一练-------Day(9)
本专栏为c语言练习专栏,适合刚刚学完c语言的初学者。本专栏每天会不定时更新,通过每天练习,进一步对c语言的重难点知识进行更深入的学习。 今日练习题关键字:字符个数统计 多数元素 投票法 💓博主csdn个人主页…...
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数据结构与算法实现(目录) 答案在此:二叉查找树(binary search tree)(答案) 写在前面 部分内容参《算法导论》 基本接口实现 1 删除 删除值为value的第一个节点 删除叶子节点1 删除叶子节…...
windows环境装MailHog
背景:win10系统,windows 宝塔,laravel 项目,邮件相关需要装一个MailHog 下载地址:https://sourceforge.net/projects/mailhog.mirror/ 直接下载,下载后双击运行就可以了,系统可能提示”不信任“…...
Ubuntu 22.04.2 LTS 安装python3.6后报错No module named ‘ufw‘
查明原因: vim /usr/sbin/ufw 初步判断是python版本的问题。 # 查看python3软链接 ll /usr/bin/python3 将python3的软链接从python3.6换成之前的3.10,根据自己电脑情况。 可以查看下 /usr/bin 下有什么 我这是python3.10 所以解决办法是 # 移除py…...
Flutter小功能实现-咖啡店
1 导航栏实现 效果图: 1.Package google_nav_bar: ^5.0.6 使用文档: google_nav_bar | Flutter Package 2.Code //MyBottomNavBar class MyBottomNavBar extends StatelessWidget {void Function(int)? onTabChange;MyBottomNavBar({super.key, …...
Unity3D中Gfx.WaitForPresent优化方案
前言 在Unity中,Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染(即CPU被阻塞),这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案: 对惹,这里有一个游戏开发交流小组&…...
大型活动交通拥堵治理的视觉算法应用
大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动(如演唱会、马拉松赛事、高考中考等)期间,城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例,暖城商圈曾因观众集中离场导致周边…...
什么是库存周转?如何用进销存系统提高库存周转率?
你可能听说过这样一句话: “利润不是赚出来的,是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业,很多企业看着销售不错,账上却没钱、利润也不见了,一翻库存才发现: 一堆卖不动的旧货…...
uniapp微信小程序视频实时流+pc端预览方案
方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度WebSocket图片帧定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐RTMP推流TRTC/即构SDK推流❌ 付费方案 (部分有免费额度&#x…...
Ascend NPU上适配Step-Audio模型
1 概述 1.1 简述 Step-Audio 是业界首个集语音理解与生成控制一体化的产品级开源实时语音对话系统,支持多语言对话(如 中文,英文,日语),语音情感(如 开心,悲伤)&#x…...
MySQL 8.0 OCP 英文题库解析(十三)
Oracle 为庆祝 MySQL 30 周年,截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始,将英文题库免费公布出来,并进行解析,帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...
图表类系列各种样式PPT模版分享
图标图表系列PPT模版,柱状图PPT模版,线状图PPT模版,折线图PPT模版,饼状图PPT模版,雷达图PPT模版,树状图PPT模版 图表类系列各种样式PPT模版分享:图表系列PPT模板https://pan.quark.cn/s/20d40aa…...
是否存在路径(FIFOBB算法)
题目描述 一个具有 n 个顶点e条边的无向图,该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序,确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数,分别表示n 和 e 的值(1…...
Device Mapper 机制
Device Mapper 机制详解 Device Mapper(简称 DM)是 Linux 内核中的一套通用块设备映射框架,为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程,并配以详细的…...
mac 安装homebrew (nvm 及git)
mac 安装nvm 及git 万恶之源 mac 安装这些东西离不开Xcode。及homebrew 一、先说安装git步骤 通用: 方法一:使用 Homebrew 安装 Git(推荐) 步骤如下:打开终端(Terminal.app) 1.安装 Homebrew…...
