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

MQTTnet.Server同时支持mqtt及websocket协议

Net6后写法

 Net6前写法

Program.cs

using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using MQTTnet.AspNetCore;
using System;
using System.IO;namespace MQTTnet.Server
{public class Program{public static int WebPort { get; set; } public static void Main(string[] args){var configuration = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile("appsettings.json").Build();var appSettings = configuration.GetSection("AppSettings");WebPort = Convert.ToInt32(appSettings["WebPort"]);  CreateHostBuilder(args).Build().Run();}public static IHostBuilder CreateHostBuilder(string[] args){ return Host.CreateDefaultBuilder(args).ConfigureWebHostDefaults(webBuilder => {webBuilder.UseKestrel(o =>{o.ListenAnyIP(2883, l => l.UseMqtt());o.ListenAnyIP(WebPort); // http & websocket});webBuilder.UseStartup<Startup>();});}}
}

Startup.cs

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using MQTTnet.AspNetCore;
using MQTTnet.Server.Util.mqtt;
using System.Linq;namespace MQTTnet.Server
{public class Startup{public Startup(IConfiguration configuration){Configuration = configuration;}public IConfiguration Configuration { get; }public void ConfigureServices(IServiceCollection services){services.AddControllers();MQServer.UserName = "admin";MQServer.Password = "123456";services.AddHostedMqttServer(optionsBuilder =>{optionsBuilder.WithMaxPendingMessagesPerClient(10000)//限制每个客户端连接在 MQTT 代理上可以拥有的待处理消息数量的设置,默认值是100 .WithKeepAlive();});services.AddMqttConnectionHandler();services.AddConnections();services.AddSingleton<MQServer>();}// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.public void Configure(IApplicationBuilder app, IWebHostEnvironment env, MQServer mqttController){ if (env.IsDevelopment()){app.UseDeveloperExceptionPage();} app.UseRouting();app.UseEndpoints(endpoints =>{ endpoints.MapControllerRoute(name: "default", pattern: "{controller=Demo}/{action=Info}/{id?}");//endpoints.MapConnectionHandler<MqttConnectionHandler>("/mqtt",httpConnectionDispatcherOptions => httpConnectionDispatcherOptions.WebSockets.SubProtocolSelector =protocolList => protocolList.FirstOrDefault() ?? string.Empty);});app.UseMqttServer(server =>{ server.ValidatingConnectionAsync += MQServer.ValidateConnectionAsync;server.ClientConnectedAsync += MQServer.ClientConnectedAsync;server.ClientDisconnectedAsync += MQServer.ClientDisconnectedAsync;});}}
}

MQServer.cs

using MQTTnet.Protocol;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;namespace MQTTnet.Server.Util.mqtt
{public class MQServer{ public static string UserName { get; set; } = "admin";public static string Password { get; set; } = "123456"; static readonly HashSet<string> clientIds = new();/// <summary>/// Validates the MQTT connection./// </summary>/// <param name="args">The arguments.</param>public static Task ValidateConnectionAsync(ValidatingConnectionEventArgs args){try{if (string.IsNullOrWhiteSpace(args.UserName)){args.ReasonCode = MqttConnectReasonCode.BadUserNameOrPassword;Logger.Error($"MQServer,身份校验失败(用户名为空),ClientId:{args.ClientId}");return Task.CompletedTask;}if (clientIds.TryGetValue(args.ClientId, out var _)){args.ReasonCode = MqttConnectReasonCode.ClientIdentifierNotValid;Logger.Error($"MQServer,身份校验失败(有相同clientid已连接),ClientId:{args.ClientId}");return Task.CompletedTask;}if (args.UserName != UserName || args.Password != Password){args.ReasonCode = MqttConnectReasonCode.BadUserNameOrPassword;Logger.Error($"MQServer,身份校验失败(用户名或密码错误),ClientId:{args.ClientId},UserName:{args.UserName},Password:{args.Password}");return Task.CompletedTask;} args.ReasonCode = MqttConnectReasonCode.Success; return Task.CompletedTask;}catch (Exception ex){ Logger.Error("MQServer,ValidateConnectionAsync", ex);return Task.FromException(ex);}}public static async Task ClientConnectedAsync(ClientConnectedEventArgs args){Logger.Info($"MQServer,mqtt客户端上线,id:{args.ClientId},Endpoint:{args.Endpoint},ProtocolVersion:{args.ProtocolVersion}");clientIds.Add(args.ClientId); }/// <summary>/// Handles the client connected event./// </summary>/// <param name="args">The arguments.</param>public static async Task ClientDisconnectedAsync(ClientDisconnectedEventArgs args){Logger.Error($"MQServer,mqtt客户端离线,id:{args.ClientId},Endpoint:{args.Endpoint},DisconnectType:{args.DisconnectType},ReasonString:{args.ReasonCode}");clientIds.Remove(args.ClientId); }}
}

相关文章:

MQTTnet.Server同时支持mqtt及websocket协议

Net6后写法 Net6前写法 Program.cs using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Hosting; using MQTTnet.AspNetCore; using System; using System.IO;namespace MQTTnet.Server {public class Program{publ…...

【数据结构】二叉树(一)遍历

导言 前面以及有了堆的基础&#xff0c;现在来学习二叉树。二叉树的学习和前面的数据结构很不一样&#xff0c;前面我们主要学习用数据结构储存数据&#xff0c;以及实际手搓数据结构的增删查改&#xff1b;而学习二叉树主要是为我们以后学搜索二叉树以及后面的AVL树等数据结构…...

【C++ 贪心】1616. 分割两个字符串得到回文串|1868

本文涉及知识点 C贪心 LeetCode1616. 分割两个字符串得到回文串 给你两个字符串 a 和 b &#xff0c;它们长度相同。请你选择一个下标&#xff0c;将两个字符串都在 相同的下标 分割开。由 a 可以得到两个字符串&#xff1a; aprefix 和 asuffix &#xff0c;满足 a aprefi…...

识别秒拨风险的具体方法及策略

秒拨技术是利用家用宽带拨号上网&#xff08;PPPoE&#xff09;的特性&#xff0c;通过频繁断线重连来获取新的IP地址&#xff0c;从而构建代理服务或进行其他网络活动。这种技术使得IP地址的切换频率极高&#xff0c;加大了识别和追踪的难度。因此&#xff0c;首先需要对秒拨技…...

[Python]如何在Ubuntu中建置python venv虛擬環境,並安裝TensorFlow和OpenCV函式庫?

為了在樹莓派上實現物件影像辨識功能&#xff0c;同時不影響樹莓派原來的python運行環境&#xff0c;選擇建置python虛擬環境[Note1]是一個好方式&#xff0c;其可避免版本衝突和不同運行環境的問題。另外&#xff0c;一併在該虛擬環境中安裝TensorFlow[Note2]和OpenCV[Note3]等…...

Excel:Cells(Rows.Count, 1).End(xlUp).Row和Cells(Rows.Count, 1).End(xlUp)有什么区别

Cells(Rows.Count, 1).End(xlUp).Row 和 Cells(Rows.Count, 1).End(xlUp) 是 VBA 中用于定位 Excel 工作表中单元格的两种不同用法。以下是它们的区别&#xff1a; 1. Cells(Rows.Count, 1).End(xlUp).Row 功能: 这个表达式返回的是一个行号&#xff08;Long 类型&#xff09…...

E. Count Paths

题目 题解&#xff1a; #include <bits/stdc.h>#define forn(i, n) for (int i 0; i < int(n); i)using namespace std;int n; vector<int> a; vector<vector<int>> g;long long ans; vector<map<int, int>> cnt;void dfs(int v, int …...

集合论(ZFC)之良创关系(Well-Founded Relation)

定义在集合S中的一个二元关系&#xff08;Binary Relation&#xff09;记&#xff0c;<&#xff0c;有&#xff08;S&#xff0c;<&#xff09;。如果对于集合S的任意非空子集&#xff0c;都存在关系&#xff08;<&#xff09;下的最小元素&#xff0c;那么该关系&…...

centos 安装达梦数据库

一、环境准备 1.1、确认操作系统的版本和数据库的版本是否一致 ## 查看系统版本&#xff1a;cat /etc/redhat-release CentOS Linux release 7.5.1804 (Core)1.2、关闭防火墙和Selinux # 查看selinux是不是disabled / enforce cat /etc/selinux/config## 查看防火墙状态 fir…...

《Windows PE》6.4.1 无 DLL远程注入

本节我们将演示如何实现远程注入的两种不同方案。方案一选择远程注入代码和数据&#xff0c;方案二选择远程注入DLL。 本节必须掌握的知识点&#xff1a; 无DLL远程注入 远程注入DLL 6.4.1 无DLL远程注入 实验四十五&#xff1a;无DLL远程注入&#xff08;C语言实现&#xf…...

浙大数据结构:10-排序6 Sort with Swap(0, i)

这道题用了数环的思想&#xff0c;MOOC最后视频中也有相关介绍&#xff0c;思想还是很巧妙的 机翻 1、思想 2、 主函数 先把数据存进来&#xff0c;然后从头开始遍历&#xff0c;如果该位置数不对则anwser&#xff0c;然后遍历整个环&#xff0c;一直加anwser&#xff0c;如…...

基于vue框架的的爱心捐赠物资信息系统85gsu(程序+源码+数据库+调试部署+开发环境)系统界面在最后面。

系统程序文件列表 项目功能&#xff1a;用户,爱心项目,捐赠类型,捐赠,积分兑换,兑换,捐赠名录,捐赠去向 开题报告内容 基于Vue框架的爱心捐赠物资信息系统开题报告 一、研究背景与意义 随着社会的发展和人们生活水平的提高&#xff0c;爱心捐赠活动逐渐成为连接捐赠者与受赠…...

AI对抗AI:如何应对自动化攻击新时代?

在当今这个生成式AI迅猛发展的时代&#xff0c;自动化攻击的威胁日益加剧。 在人工智能浪潮下&#xff0c;如何利用AI对抗AI&#xff0c;从而实现全方位的网络安全防护&#xff1f; 一、AI浪潮下&#xff0c;自动化攻击加剧 AI技术的发展既带来了前所未有的挑战&#xff0c;也…...

【微服务】微服务注册:构建灵活的服务管理机制

目录 引言一、什么是微服务注册&#xff1f;1.1 服务注册中心的作用1.2 服务注册中心的工作原理1.3 示意图 二、常见的微服务注册中心2.1 各注册中心详细对比 三、微服务注册的实现方式3.1 Spring Cloud Netflix Eureka3.2 Consul3.3 Zookeeper3.4 etcd 四、微服务注册的注意事…...

AsyncTask的工作原理和缺陷

AsyncTask的工作原理及其缺陷 AsyncTask是Android平台提供的一个轻量级的异步任务类&#xff0c;它允许开发者在后台线程中执行耗时操作&#xff0c;并在操作完成后将结果回调到主线程以更新UI。AsyncTask内部封装了线程池和Handler机制&#xff0c;简化了多线程编程的复杂性。…...

【React】事件绑定的方式

1. 内联函数绑定 这是最简单直接的方式&#xff0c;即在 JSX 语法中直接传递一个内联函数。这种方式每次渲染时都会创建新的函数实例&#xff0c;可能会导致不必要的性能开销。 class MyComponent extends React.Component {render() {return (<button onClick{() > th…...

Android ImageView scaleType使用

目录 一、src设置图片资源 二、scaleType设置图片缩放类型 三、scaleType具体表现 matrix&#xff1a; fitXY: fitStart&#xff1a; fitCenter&#xff1a; fitEnd: Center&#xff1a; centerCrop: centerInside&#xff1a; 控制ImageView和图片的大小保持一致…...

【PhpSpreadsheet】ThinkPHP5+PhpSpreadsheet实现批量导出数据

目录 前言 一、安装 二、API使用 三、完整实例 四、效果图 前言 为什么使用PhpSpreadsheet&#xff1f; 由于PHPExcel不再维护&#xff0c;所以建议使用PhpSpreadsheet来导出exlcel&#xff0c;但是PhpSpreadsheet由于是个新的类库&#xff0c;所以只支持PHP7.1及以上的版…...

Python剪辑视频

import os from moviepy.editor import VideoFileClipvideo_dir r"E:\学习\视频剪辑" s_video_file "1.mp4" d_video_file "剪辑片段1.mp4" s_video_path os.path.join(video_dir, s_video_file) # 原视频文件路径 d_video_path os.path…...

LabVIEW提高开发效率技巧----高效文件I/O

在LabVIEW开发中&#xff0c;文件I/O操作常常是性能瓶颈之一&#xff0c;特别是处理大数据时&#xff0c;如何高效地存储和读取数据显得尤为重要。本文将详细介绍如何利用TDMS Streaming来实现高效的文件I/O&#xff0c;并结合具体例子说明在实际开发中的应用技巧。 1. 什么是T…...

docker详细操作--未完待续

docker介绍 docker官网: Docker&#xff1a;加速容器应用程序开发 harbor官网&#xff1a;Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台&#xff0c;用于将应用程序及其依赖项&#xff08;如库、运行时环…...

通过Wrangler CLI在worker中创建数据库和表

官方使用文档&#xff1a;Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后&#xff0c;会在本地和远程创建数据库&#xff1a; npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库&#xff1a; 现在&#xff0c;您的Cloudfla…...

Python实现prophet 理论及参数优化

文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候&#xff0c;写过一篇简单实现&#xff0c;后期随着对该模型的深入研究&#xff0c;本次记录涉及到prophet 的公式以及参数调优&#xff0c;从公式可以更直观…...

有限自动机到正规文法转换器v1.0

1 项目简介 这是一个功能强大的有限自动机&#xff08;Finite Automaton, FA&#xff09;到正规文法&#xff08;Regular Grammar&#xff09;转换器&#xff0c;它配备了一个直观且完整的图形用户界面&#xff0c;使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...

SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)

上一章用到了V2 的概念&#xff0c;其实 Fiori当中还有 V4&#xff0c;咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务)&#xff0c;代理中间件&#xff08;ui5-middleware-simpleproxy&#xff09;-CSDN博客…...

GitFlow 工作模式(详解)

今天再学项目的过程中遇到使用gitflow模式管理代码&#xff0c;因此进行学习并且发布关于gitflow的一些思考 Git与GitFlow模式 我们在写代码的时候通常会进行网上保存&#xff0c;无论是github还是gittee&#xff0c;都是一种基于git去保存代码的形式&#xff0c;这样保存代码…...

push [特殊字符] present

push &#x1f19a; present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中&#xff0c;push 和 present 是两种不同的视图控制器切换方式&#xff0c;它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...

并发编程 - go版

1.并发编程基础概念 进程和线程 A. 进程是程序在操作系统中的一次执行过程&#xff0c;系统进行资源分配和调度的一个独立单位。B. 线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。C.一个进程可以创建和撤销多个线程;同一个进程中…...

代码规范和架构【立芯理论一】(2025.06.08)

1、代码规范的目标 代码简洁精炼、美观&#xff0c;可持续性好高效率高复用&#xff0c;可移植性好高内聚&#xff0c;低耦合没有冗余规范性&#xff0c;代码有规可循&#xff0c;可以看出自己当时的思考过程特殊排版&#xff0c;特殊语法&#xff0c;特殊指令&#xff0c;必须…...

django blank 与 null的区别

1.blank blank控制表单验证时是否允许字段为空 2.null null控制数据库层面是否为空 但是&#xff0c;要注意以下几点&#xff1a; Django的表单验证与null无关&#xff1a;null参数控制的是数据库层面字段是否可以为NULL&#xff0c;而blank参数控制的是Django表单验证时字…...