C#MQTT协议应用

news2024/9/19 21:18:30

1 ,MQTT介绍:
MQTT详解以及实际操作_mqtt使用-CSDN博客

2,MQTT应用:

C#MQTT编程06--MQTT服务器和客户端(winform版)_c# mqtt服务器-CSDN博客

3,MQTT实例:

 

效果 

代码:

服务端

  public partial class Form1 : Form
    {
        Timer timer = new Timer();
        List<ClientItem> clients = new List<ClientItem>();
        public Form1()
        {
            InitializeComponent();
            timer.Interval = 500;
            timer.Tick += Timer_Tick;
            timer.Start();
            InitSetting();
        }
        private void Timer_Tick(object sender, EventArgs e)
        {
            toolStripStatusDateTime.Text = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss");
        }
        void InitSetting()
        {
            //获取本机所有的IP4地址
            string[] ips = Dns.GetHostAddresses(Environment.MachineName).Where(item => !item.IsIPv6LinkLocal).Select(item => item.ToString()).ToArray();
            comboIp_List.DataSource = ips;
            txtPort.Text = "8000";
            txtUserName.Text = "sa";
            txtPwd.Text = "1";
        }
        IMqttServer mqttServer;
        private void btnStart_Click(object sender, EventArgs e)
        {
            if (btnStart.Text.Equals("开始"))
            {
                IMqttServerOptions options = new MqttServerOptionsBuilder()
               .WithConnectionBacklog(10)
               .WithDefaultEndpointBoundIPAddress(IPAddress.Parse(comboIp_List.Text.Trim()))
               .WithDefaultEndpointPort(Convert.ToInt32(txtPort.Text.Trim()))
               .WithDefaultCommunicationTimeout(TimeSpan.FromMilliseconds(5000))
               .WithConnectionValidator(context =>
               {
                   //验证
                   if (ck_UserPwd.Checked)
                   {
                       if (!context.Username.Equals(txtUserName.Text))
                       {
                           context.ReasonCode = MQTTnet.Protocol.MqttConnectReasonCode.BadUserNameOrPassword;
                          
                           
                       }
                       if (!context.Password.Equals(txtPwd.Text))
                       {
                           context.ReasonCode = MQTTnet.Protocol.MqttConnectReasonCode.BadUserNameOrPassword;
                         
                       }
                   }
                   else
                   {
                       context.ReasonCode = MQTTnet.Protocol.MqttConnectReasonCode.Success;
                   }
               }).Build();
                mqttServer = new MqttFactory().CreateMqttServer();
                mqttServer.ApplicationMessageReceivedHandler = new MqttApplicationMessageReceivedHandlerDelegate(ApplicationMessageReceived);
                //服务开始事件
                mqttServer.StartedHandler = new MqttServerStartedHandlerDelegate(MqttServer_StartedAsync);
                //服务停止事件
                mqttServer.StoppedHandler = new MqttServerStoppedHandlerDelegate(MqttServer_StoppedAsync);
                //客户端连接事件
                mqttServer.ClientConnectedHandler = new MqttServerClientConnectedHandlerDelegate(MqttServer_ClientConnectedAsync);
                //客户端断开连接事件
                mqttServer.ClientDisconnectedHandler = new MqttServerClientDisconnectedHandlerDelegate(MqttServer_ClientDisconnectedAsync);
                //客户端订阅事件
                mqttServer.ClientSubscribedTopicHandler = new MqttServerClientSubscribedTopicHandlerDelegate(MqttServer_ClientSubscribedTopicAsync);
                //客户端取消订阅事件
                mqttServer.ClientUnsubscribedTopicHandler = new MqttServerClientUnsubscribedTopicHandlerDelegate(MqttServer_ClientUnsubscribedTopicAsync);
               
                mqttServer.StartAsync(options);
           
                if (mqttServer.IsStarted)
                {
                    btnStart.Text = "断开";
                    btnStart.BackColor = Color.Green;
                    comboIp_List.Enabled = txtPort.Enabled = false;
                }
            }
            else
            {
                mqttServer.StopAsync().Wait();
                if (!mqttServer.IsStarted)
                {
                    btnStart.Text = "开始";
                    btnStart.BackColor = Color.Red;
                    comboIp_List.Enabled = txtPort.Enabled = true;
                }
                mqttServer.Dispose();
            }
        }
        private Task MqttServer_ClientUnsubscribedTopicAsync(MqttServerClientUnsubscribedTopicEventArgs arg)
        {
            //客户端取消订阅事件
            string msg = $"客户端ID:[{arg.ClientId}] 取消主题:[{arg.TopicFilter}] 订阅";
            AddLog(1, msg);
            //取消订阅
            ClientItem client = clients.FirstOrDefault(item => item.ClientID.Equals(arg.ClientId));
            client?.Topics.RemoveAll(item => item.Topic.Equals(arg.TopicFilter));
            return Task.FromResult(arg);
        }
        private Task MqttServer_ClientSubscribedTopicAsync(MqttServerClientSubscribedTopicEventArgs arg)
        {
            //客户端订阅事件
            string msg = $"客户端ID:[{arg.ClientId}]订阅主题:[{arg.TopicFilter.Topic}],Qos:[{arg.TopicFilter.QualityOfServiceLevel}]";
            AddLog(0, msg);
            TopicItem topic = new TopicItem { QualityOfServiceLevel = arg.TopicFilter.QualityOfServiceLevel, Topic = arg.TopicFilter.Topic };
            ClientItem client = clients.FirstOrDefault(item => item.ClientID.Equals(arg.ClientId));
            client?.Topics.Add(topic);
            return Task.FromResult(arg);
        }
        private Task MqttServer_ClientDisconnectedAsync(MqttServerClientDisconnectedEventArgs arg)
        {
            //客户端断开事件
            string msg = $"客户端ID:[{arg.ClientId}] 断开连接,EndPoint:{arg.Endpoint},断开连接类型:{arg.DisconnectType}";
            AddLog(1, msg);
            //移除该Client
            clients.RemoveAll(item => item.ClientID.Equals(arg.ClientId));
            //更新ListBox
            UpdateClientList();
            return Task.FromResult(arg);
        }
        private Task MqttServer_ClientConnectedAsync(MqttServerClientConnectedEventArgs arg)
        {
            //客户端连接事件
            string msg = $"客户端ID:[{arg.ClientId}]连接 ,EndPoint:{arg.Endpoint},UserName: {arg.UserName}";
            AddLog(0, msg);
            ClientItem client = new ClientItem
            {
                ClientID = arg.ClientId,
                EndPoint = arg.Endpoint

            };
            clients.Add(client);
            //更新ListBox
            UpdateClientList();
            return Task.FromResult(arg);
        }
        private Task ApplicationMessageReceived(MqttApplicationMessageReceivedEventArgs arg)
        {
            //客户端MessageReceived事件
            string msg = $"收到消息:发送者ID:[{arg.ClientId}] QoS:{arg.ApplicationMessage.QualityOfServiceLevel} topic:{arg.ApplicationMessage.Topic}, 内容:{arg.ApplicationMessage.ConvertPayloadToString()}";
            AddLog(1, msg);
            return Task.FromResult(arg);
        }
        private Task MqttServer_StoppedAsync(EventArgs arg)
        {
            //服务停止事件
            string msg = $"服务停止";
            AddLog(1, msg);
            clients.Clear();
            return Task.FromResult(arg);
        }
        private Task MqttServer_StartedAsync(EventArgs arg)
        {
            //服务开启事件
            string msg = $"服务开启";
            AddLog(0, msg);
            return Task.FromResult(arg);
        }
     
        private void ck_UserPwd_CheckedChanged(object sender, EventArgs e)
        {
            txtUserName.Enabled = txtPwd.Enabled = ck_UserPwd.Checked;
        }
        void AddLog(int cate, string msg)
        {
            if (lstview_Note.InvokeRequired)
            {
                this.Invoke(new Action(() =>
                {
                    ListViewItem item = new ListViewItem();
                    item.ImageIndex = cate;
                    item.SubItems.Add(DateTime.Now.ToString("HH:mm:ss"));
                    item.SubItems.Add(msg);
                    lstview_Note.Items.Add(item);
                    lstview_Note.EnsureVisible(lstview_Note.Items.Count - 1);
                    toolStripStatusConnectCount.Text = clients.Count.ToString();
                }));
            }
            else
            {
                ListViewItem item = new ListViewItem();
                item.ImageIndex = cate;
                item.SubItems.Add(DateTime.Now.ToString("HH:mm:ss"));
                item.SubItems.Add(msg);
                lstview_Note.Items.Add(item);
                lstview_Note.EnsureVisible(lstview_Note.Items.Count - 1);
                toolStripStatusConnectCount.Text = clients.Count.ToString();
            }
           
           
        }
        private void btnCreateClient_Click(object sender, EventArgs e)
        {
            ClientFrm frm = new ClientFrm();
            frm.Show();
        }

        private void lst_Client_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (lst_Client.SelectedItem != null)
            {
                ClientItem item = lst_Client.SelectedItem as ClientItem;
                lst_Topic.DataSource = item.Topics.Select(a => $"Topic:{a.Topic},QoS:{a.QualityOfServiceLevel}").ToArray();
            }
        }
        /// <summary>
        /// 更新clientList 列表
        /// </summary>
        void UpdateClientList()
        {
            this.Invoke(new Action(() => {
                lst_Client.Items.Clear();
                foreach (var item in clients)
                {
                    lst_Client.Items.Add(item);
                }
                toolStripStatusConnectCount.Text = clients.Count.ToString();
            }));
          
           
        }
    }
 class ClientItem
    {
        public List<TopicItem> Topics { get; set; } = new List<TopicItem>();

        public string ClientID { get; set; }
        public string EndPoint { get; set; }
        public override string ToString()
        {
            return $"{ClientID};{EndPoint}";
        }

    }
    class TopicItem
    {
        public string Topic { get; set; }
        /// <summary>
        /// 服务质量级别,QoS0 (Almost One):至多一次,只发送一次,会发生消息丢失或重复。QoS1(Atleast Once): 至少一次,确保消息到达,但消息可能重复发送。QoS2(Exactly Once):只有一次,确保消息只到达一次。
        /// </summary>
        public MqttQualityOfServiceLevel QualityOfServiceLevel { get; set; }
    }

客户端

 public partial class ClientFrm : Form
    {
        Timer timer = new Timer();
        public ClientFrm()
        {
            InitializeComponent();
            timer.Interval = 500;
            timer.Tick += Timer_Tick;
            timer.Start();
            InitSetting();
        }
        private void Timer_Tick(object sender, EventArgs e)
        {
            toolStripStatusDateTime.Text = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss");
        }
        void InitSetting()
        {
            //获取本机所有的IP4地址
            string[] ips = Dns.GetHostAddresses(Environment.MachineName).Where(item => !item.IsIPv6LinkLocal).Select(item => item.ToString()).ToArray();
            comboIp_List.DataSource = ips;
            txtPort.Text = "8000";
            txtUserName.Text = "sa";
            txtPwd.Text = "1";
            comboQoS.DataSource = Enum.GetNames(typeof(MQTTnet.Protocol.MqttQualityOfServiceLevel));
        }
        IMqttClient client;
        private void btnConnect_Click(object sender, EventArgs e)
        {
            //  txtClientId.Text = Guid.NewGuid().ToString();
            if (string.IsNullOrEmpty(txtClientId.Text.Trim()))
            {
                MessageBox.Show("ClientId不能为空!");
                return;
            }
            if (btnConnect.Text.Equals("连接"))
            {
                client = new MqttFactory().CreateMqttClient();
                MqttClientOptionsBuilder builder = new MqttClientOptionsBuilder()
                       .WithClientId(txtClientId.Text.Trim())
                       .WithCommunicationTimeout(TimeSpan.FromMilliseconds(50000))
                       .WithTcpServer(comboIp_List.Text.Trim(), Convert.ToInt32(txtPort.Text.Trim()));
                if (ck_UserPwd.Checked)
                {
                    builder.WithCredentials(txtUserName.Text.Trim(), txtPwd.Text.Trim());
                }
                IMqttClientOptions option = builder.Build();
                //消息接收事件
                client.ApplicationMessageReceivedHandler = new MqttApplicationMessageReceivedHandlerDelegate(Client_ApplicationMessageReceivedAsync);
                //客户端连接事件
                client.ConnectedHandler = new MqttClientConnectedHandlerDelegate(Client_ConnectedAsync);
               // client.UseConnectedHandler
                //客户端连接断开事件
                client.DisconnectedHandler = new MqttClientDisconnectedHandlerDelegate(Client_DisconnectedAsync);
               
                client.ConnectAsync(option);
               
            }
            else
            {
                client.DisconnectAsync().Wait();
                UpdateStatus(client.IsConnected);
                client.Dispose();
            }
        }
        private Task Client_DisconnectedAsync(MqttClientDisconnectedEventArgs arg)
        {
            //客户端断开事件
            string msg = $" 断开连接, 返回结果:{arg.Reason}";
            AddLog(1, msg);
            UpdateStatus(client.IsConnected);
            return Task.FromResult(arg);
        }
        private Task Client_ConnectedAsync(MqttClientConnectedEventArgs arg)
        {
            //客户端连接事件
            string msg = $"客户端ID 连接,结果:{arg.ConnectResult.ResultCode}";
            AddLog(0, msg);
            UpdateStatus(client.IsConnected);
            
            return Task.FromResult(arg);
        }
        private Task Client_ApplicationMessageReceivedAsync(MqttApplicationMessageReceivedEventArgs arg)
        {
            //客户端取消订阅事件
            string msg = $"消息ClientId:[{arg.ClientId}] , topic:[{arg.ApplicationMessage.Topic}], 内容:[{arg.ApplicationMessage.ConvertPayloadToString()}],QoS:[{arg.ApplicationMessage.QualityOfServiceLevel}]";
            AddLog(1, msg);
            return Task.FromResult(arg);
        }
        private void ck_UserPwd_CheckedChanged(object sender, EventArgs e)
        {
            txtUserName.Enabled = txtPwd.Enabled = ck_UserPwd.Checked;
        }
        void AddLog(int cate, string msg)
        {
            this.Invoke(new Action(() =>
            {
                ListViewItem item = new ListViewItem();
                item.ImageIndex = cate;
                item.SubItems.Add(DateTime.Now.ToString("HH:mm:ss"));
                item.SubItems.Add(msg);
                lstview_Note.Items.Add(item);
                lstview_Note.EnsureVisible(lstview_Note.Items.Count - 1);
            }));
        }
        private async void btnSubscribed_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrWhiteSpace(txtTopic.Text))
            {
                MessageBox.Show("主题不能为空!");
                return;
            }
            //主题订阅
            if (client?.IsConnected == true)
            {
                //QoS0 (Almost One):至多一次,只发送一次,会发生消息丢失或重复。
                //QoS1(Atleast Once): 至少一次,确保消息到达,但消息可能重复发送
                //QoS2(Exactly Once):只有一次:只有一次,确保消息只到达一次。
                var result = await client.SubscribeAsync(new MqttTopicFilter()
                {
                    QualityOfServiceLevel = (MqttQualityOfServiceLevel)Enum.Parse(typeof(MqttQualityOfServiceLevel), comboQoS.Text.Trim()),
                    Topic = txtTopic.Text.Trim()
                });
                StringBuilder sb = new StringBuilder();
                foreach (var item in result.Items)
                {
                    sb.AppendLine($"订阅主题:[{item.TopicFilter.Topic}],QoS:[{item.TopicFilter.QualityOfServiceLevel}],ReturnCode:[{item.ResultCode}]");
                }
                AddLog(0, sb.ToString());
            }
            else
            {
                MessageBox.Show("请先连接服务!");
            }
        }
        private async void btnPublish_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrWhiteSpace(txtMsgTopic.Text.Trim()))
            {
                MessageBox.Show("主题不能为空!");
                return;
            }
            //发布信息
            if (client?.IsConnected == true)
            {
                var result = await client.PublishAsync(new MqttApplicationMessage
                {
                    Topic = txtMsgTopic.Text.Trim(),
                    QualityOfServiceLevel = MqttQualityOfServiceLevel.ExactlyOnce,
                     Payload =Encoding.UTF8.GetBytes( txtMsgContent.Text.Trim())
                });
                string msg = $"发布消息:{txtMsgContent.Text} Topic:{txtMsgTopic.Text.Trim()} 结果:{result.ReasonCode}";
                AddLog(0, msg);
            }
            else
            {
                MessageBox.Show("请先连接服务!");
            }
        }
        void UpdateStatus(bool isConnected)
        {
            this.Invoke(new Action(() =>
            {
                if (!isConnected)
                {
                    btnConnect.Text = "连接";
                    btnConnect.BackColor = Color.Red;
                    comboIp_List.Enabled = txtPort.Enabled = true;
                }
                else
                {
                    btnConnect.Text = "断开";
                    btnConnect.BackColor = Color.Green;
                    comboIp_List.Enabled = txtPort.Enabled = false;
                }
            }));
          
        }

        private async void btnUnsubscribed_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrWhiteSpace(txtTopic.Text))
            {
                MessageBox.Show("主题不能为空!");
                return;
            }
            //主题订阅
            if (client?.IsConnected == true)
            {
                //QoS0 (Almost One):至多一次,只发送一次,会发生消息丢失或重复。
                //QoS1(Atleast Once): 至少一次,确保消息到达,但消息可能重复发送
                //QoS2(Exactly Once):只有一次:只有一次,确保消息只到达一次。
                var result = await client.UnsubscribeAsync(txtTopic.Text.Trim());
              
                StringBuilder sb = new StringBuilder();
                foreach (var item in result.Items)
                {
                    sb.AppendLine($"取消主题:[{item.TopicFilter}]订阅,ReturnCode:[{item.ReasonCode}]");
                }
                AddLog(0, sb.ToString());
            }
            else
            {
                MessageBox.Show("请先连接服务!");
            }
        }
    }

demo链接

https://download.csdn.net/download/lingxiao16888/89616009

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1985086.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

亚马逊ERP全功能支持企业贴牌独立部署,可对外销售

亚马逊全功能 ERP&#xff01; 1. 对于亚马逊企业来说需要一款选品、财务管理、部署等为一体的性价比高的 ERP&#xff0c;而这款 ERP 功能齐全且性价比高。 2. 其铺货、采集、选品支持国内淘宝、拼多多、1688 等&#xff0c;以及国外亚马逊、速卖通等所有热门平台采集。采集…

壁纸头像小程序uniapp版(附源码)

壁纸头像类小程序是最热门的小程序类型之一&#xff0c;也是个人开通流量主的最佳选择。 技术栈 uniApp UniCloud Vue 功能 隐私授权 壁纸列表 壁纸预览 头像列表 图片下载到本地相册 流量主 banner、激励、插屏 技术功能 微信隐私保护指引 图片下载到本地相册 自定义头部组件…

洗地机哪个牌子好?分享四款口碑最好的洗地机

随着现代家居生活节奏的加快&#xff0c;洗地机作为家庭清洁的得力助手&#xff0c;其重要性日益凸显。市面上洗地机品牌繁多&#xff0c;如何选择一款性价比高、口碑良好的洗地机成为了消费者关注的焦点。本文将为大家精心挑选并分享四款备受好评的洗地机品牌及型号&#xff0…

11万条心理健康问答ACCESS\EXCEL数据库

今天从一个心理健康知识网站采集了11万多条的心理健康问答文章内容&#xff0c;感觉非常适用于心理健康、心理测试类产品的附加项&#xff0c;数据量很多正好提供各类关键词的搜索。 数据仅提供Microsoft Office Access数据库&#xff0c;扩展名是MDB。 MDB文件大小有350M左右&…

Python处理异常用操作笔记

在编写Python程序时&#xff0c;我们经常会遇到各种异常、错误等。对于异常处理的常用操作&#xff0c;记录如下&#xff1a; 1、try-except try-except语句是Python中最常用的异常处理结构。它的基本语法如下&#xff1a; try:# 尝试执行的代码块 except ExceptionType:# 当发…

多人在线像素涂鸦网页源码

多人在线像素涂鸦网页源码node.js项目&#xff0c;100100的像素格画布&#xff0c;可供多人在线涂鸦&#xff0c;画布内容实时刷新。 源码下载:多人在线像素涂鸦网页源码.zip 包含完整搭建教程 仍有不完善的地方&#xff1a; 1.没有限制一分钟内的涂鸦次数&#xff0c;这会…

大模型日报|20 篇必读的大模型论文

大家好&#xff0c;今日必读的大模型论文来啦&#xff01; 1.智谱AI 发布视频大模型 CogVideoX 技术报告 Sora 发布近半年之后&#xff0c;业内仍未出现一个开源的、满足商业级应用需求的视频生成模型。 今天&#xff0c;智谱AI 便推出了首个开源的商用级视频生成模型——Co…

Ubuntu 20.04 中安装 Nginx (通过传包编译的方式)、开启关闭防火墙、开放端口号

文章目录 前言一、安装包下载二、上传服务器并解压缩三、依赖配置安装四、生成编译脚本五、编译六、查看是否编译完成七、开始安装八、查看是否安装成功九、设置为开机自启动 前言 参考大佬文章并在基础上做了点修改&#xff0c;发篇文章记录下 防止下次遇到。 参考文章&#…

软件设计之CSS

软件设计之CSS 【狂神说Java】CSS3最新教程快速入门通俗易懂 学习内容&#xff1a; 软件开发技能点参照&#xff1a;软件开发&#xff0c;小白变大佬&#xff0c;这套学习路线让你少走弯路是认真的&#xff0c;欢迎讨论 软件开发技能点顺序参照&#xff1a;Java学习完整路线…

【Java】多线程精简笔记

进程和线程 进程是系统资源分配的基本单位&#xff0c;线程是系统调度的基本单位进程是程序正在运行的实例&#xff0c;里面包含着线程进程有独立的内存和资源&#xff0c;线程共用内存&#xff08;工作内存独有&#xff0c;主内存共用&#xff09;和资源线程比进程更加轻量&am…

Ubuntu防火墙相关命令

在Ubuntu系统中&#xff0c;启用防火墙可以通过ufw&#xff08;Uncomplicated Firewall&#xff09;来完成。以下是如何启用和配置ufw的步骤&#xff1a; 1.安装ufw&#xff08;如果尚未安装&#xff09; sudo apt update sudo apt install ufw2Ubuntu启用防火墙ufw&#xff1…

代码签名证书申请教程

代码签名证书的申请流程可以概括为以下几个步骤&#xff0c;这些步骤是目前可申请代码签名证书的几个云服务厂商的大致流程&#xff1a; 首先了解一下代码签名证书的种类&#xff1a; 标准代码签名证书&#xff08;一般泛指OV代码签名证书&#xff09;&#xff1a;适用于个人…

6 大推荐给开发者的无代码工具

在不断发展的软件开发领域&#xff0c;无代码工具正迅速普及。 最初&#xff0c;这些工具是为非技术背景的业务用户设计的&#xff0c;而如今&#xff0c;它们对开发者来说也同样不可或缺。 无代码工具结合了效率、灵活性和创新性&#xff0c;让开发者能够在无需编写传统代码…

Windows环境部署AI智能聊天应用LobeChat并实现远程对话实操流程

目录 ​编辑 前言 1. LobeChat对我们有哪些帮助? 2. 本地安装LobeChat 3. 如何使用LobeChat工具 4. 安装Cpolar内网穿透 5. 实现公网访问LobeChat 6. 固定LobeChat公网地址 前言 作者简介&#xff1a; 懒大王敲代码&#xff0c;计算机专业应届生 今天给大家聊聊Window…

RTSP系列一:RTSP协议介绍

RTSP系列&#xff1a; RTSP系列一&#xff1a;RTSP协议介绍-CSDN博客 RTSP系列二&#xff1a;RTSP协议鉴权-CSDN博客 RTSP系列三&#xff1a;RTP协议介绍-CSDN博客 RTSP系列四&#xff1a;RTSP Server/Client实战项目-CSDN博客 目录 一、RTSP协议介绍 二、RTSP信令 三、…

梅特勒金属探测器检测仪维修SAFELINE V3-QF1

梅特勒L系列和HDS管道式金属检测机主要用于食品行业&#xff0c;检测液态或者粘稠的产品&#xff0c;因为这类产品都是通过管道传输。 梅特勒HDS管道式系统为肉食加工和火腿类产品的检测需求度身制造,可与多种填充机联接,能够方便的介入各类加工生产线。 梅特勒T和ST系列金属检…

【091】基于SpringBoot+Vue实现的超市管理系统

系统介绍 基于SpringBootVue实现的超市管理系统 基于SpringBootVue实现的超市管理系统采用前后端分离的架构方式&#xff0c;系统分为管理员、员工两种角色&#xff0c;实现了销售管理、人事管理、个人中心、库存管理、会员管理、系统管理、商品管理等功能模块 技术选型 开发…

二十七、【人工智能】【机器学习】- 【数学基础】 之数学要素

目录 前言 数学基础 数学基础进阶 高级数学加减法 高级数学乘法 总结 前言&#xff1a; 在数学的广阔宇宙中&#xff0c;有一颗璀璨的星辰&#xff0c;它既神秘又迷人&#xff0c;这便是复数——一个融合了实数与虚数的世界。复数&#xff0c;用数学语言表示为 CC&#…

dpdk调试

1、gdb调试coredump dpdk的Makefile加上-g编译 ulimit -c unlimited echo "/home/core/core-%e-%p-%t" > /proc/sys/kernel/core_pattern

触发邮件API接口与第三方系统集成的方法?

触发邮件API接口的性能优化策略&#xff1f;如何管理API接口&#xff1f; 触发邮件API接口成为了不可或缺的工具&#xff0c;不仅能自动化邮件发送&#xff0c;还能与第三方系统无缝集成&#xff0c;提高工作效率。AokSend将探讨如何使用触发邮件API接口与第三方系统进行集成的…