首页 > 其他分享 >MQTTnet.Server同时支持mqtt及websocket协议

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

时间:2024-10-15 16:11:08浏览次数:1  
标签:websocket args ClientId Server MQTTnet static using public MQServer

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); 
        }
    }
}

 

 

标签:websocket,args,ClientId,Server,MQTTnet,static,using,public,MQServer
From: https://www.cnblogs.com/chen1880/p/18467753

相关文章

  • sqlserver 里的UNION 关键字是啥含义
    在SQLServer中,UNION是一种用于合并两个或多个SELECT语句结果集的操作符。它允许你将来自不同表或相同表但基于不同条件的查询结果合并成一个单独的结果集。使用UNION时,需要注意以下几点:列数和数据类型:所有SELECT语句必须返回相同数量的列,并且相应列的数据类型必须兼......
  • Chromium 中HTML5 WebSocket收发消息分析c++(一)
    一、WebSocket前端接口定义:WebSocket 对象提供了用于创建和管理 WebSocket 连接,以及可以通过该连接发送和接收数据的API。使用 WebSocket() 构造函数来构造一个 WebSocket。构造函数WebSocket(url[,protocols])返回一个 WebSocket 对象。常量ConstantValueWeb......
  • Chromium 中HTML5 WebSocket收发消息分析c++(二)
    看下websocket调用过程:基本定义参考上一篇:Chromium中HTML5WebSocket收发消息分析c++(一)-CSDN博客一、前端测试用例 参考:HTML5WebSocket|菜鸟教程(runoob.com) websocket.html文件如下:<!DOCTYPEHTML><html><head><metacharset="utf-8"><title>Web......
  • WebServer构建响应 && 发送响应
    1.构建响应构建响应流程如下确认方法根据不同方法,以不同方法提参确认访问资源如果用户的URL没有指明要访问的某种资源(路径),虽然浏览器默认会添加/,但是依旧没有告知服务器,要访问什么资源此时,默认返回对应服务的首页这里的/不是Linux服务器的根目录,通常是http服务器设......
  • SQLServer数据库日志太大处理方式
    SQLServer数据库日志太大处理方式1.1 如下图,点击连接登陆数据库1.2 如下图,打开数据库属性窗口1.3 如下图,更改数据库恢复模式1.4 如下图,收缩数据库日志到这里已经完成了,数据库的日志收缩1.5 如下图,数据库恢复模式修改为完整至此,完成。......
  • 4. WebSockets
    4.WebSockets4.1.WebSocket介绍WebSocket协议RFC6455提供了一种标准化方法,可以通过单个TCP连接在Client端和服务器之间构建全双工双向通信通道。它是与HTTP不同的TCP协议,但旨在通过端口80和443在HTTP上工作,并允许重复使用现有的防火墙规则。WebSocket交互......
  • ef8解决sql2008R2不支持fetch命令问题:optionsBuilder.UseSqlServer(sConn, options =>
    netcoreer8.sql2012支持fetch命令,sql2008r2不支持fetch命令,调用ef的skip(100).take(10)时,会报错:ERROR[.NETTPWorker](D:\Design\CSharp\海宏发票查重报销管理\iPublic\公共\BaseApiController.cs:114)-资料维护.Pages.CommBase.FaPiaoTypeApiController.query::'OFFSET......
  • H3C UniServer R4900 G5创建 RAID卷【图解】
    正常开机,弹出选择按键选择Esc2.进入此页面下拉可以换成中文语言(能看懂英文的忽略)3.开启RAID功能,选择高级→平台配置→PCH配置→PCHSATA配置→将配置SATA为改成RAID,然后F4保存并重启4.重启之后继续选择Esc进入BIOS→选择高级→动态设备配置菜单→选择自己的阵列→......
  • 从SQL Server过渡到PostgreSQL:理解模式的差异
    从SQLServer过渡到PostgreSQL:理解模式的差异 从SQLServer过渡到PostgreSQL:理解模式的差异前言随着越来越多的企业转向开源技术,商业数据库管理员和开发者也逐渐面临向PostgreSQL迁移的需求。虽然SQLServer和PostgreSQL共享许多数据库管理系统(RDBMS)的基本概念,但它们在处......
  • GeoServer-发布WMTS切片服务
    转自:https://blog.csdn.net/weixin_58424264/geoServer: http://localhost:8080/geoserver/web/?1默认账号:admin密码:geoserver发布WMTS服务步骤1.新建gridsets,选择合适的层数以及坐标系   2.新建工作区  仿照别人的设置  3.新建数据存储,根据资源类型找......