C#实现MQTT over WebSocket

如何在网页端实现MQTT消息的发布和订阅?

  • 实现MQTT功能,可以发布和订阅主题
  • 通过WebSocket协议将MQTT消息转发给对应的网页端

带着这个实现思路,采用C#控制台程序实现MQTT服务端功能,web端可以直接使用websocket插件与服务端双向通讯。

  1. 新建C#控制台程序,.net framework框架版本4.5.2
  2. 引用Fleck框架,版本1.2.0
  3. 引用MQTTnet框架,版本4.3.1.873

1、WebSocket功能实现

socketDic 字典key值记录每个客户端,value记录每个客户端对应的SN,代表设备的序列号;

每当有网页端客户端连接的时候,自动将客户端套接字加入字典中;

每当网页关闭,服务端自动断开客户端套接字连接,并从缓存字典中移除此客户端套接字;

当网页端客户端套接字发送包含SN:开头的字符,表示网页端发送了设备的SN,服务端接收此消息,并解析设备SN,并与对应的客户端套接字绑定对应关系,在缓存字典中维护对应关系。

class Server
{static Dictionary<IWebSocketConnection, string> socketDic = new Dictionary<IWebSocketConnection, string>();static void Main(){FleckLog.Level = LogLevel.Debug;var server = new WebSocketServer("ws://0.0.0.0:8181");//var socketDic = new Dictionary<IWebSocketConnection, string>();server.Start(socket =>{socket.OnOpen = () =>{Console.WriteLine("Open!");socketDic.Add(socket, null);};socket.OnClose = () =>{Console.WriteLine("Close!");socketDic.Remove(socket);};socket.OnMessage = message =>{if (message.Contains("SN:") && socketDic.ContainsKey(socket)){socketDic[socket] = message.Replace("SN:", "");}};});Client();var input = Console.ReadLine();while (input != "exit"){foreach (var socket in socketDic.ToList()){socket.Key.Send(input);}input = Console.ReadLine();}}
}

2、MQTT功能实现

MQTT服务器采用EMQX公共服务器测试,服务器域名:broker.emqx.io,端口:1883,用户名:emqx_test,密码:emqx_test

订阅主题名:123、12345

MQTT接收消息事件ApplicationMessageReceivedAsync,判断消息主题与缓存字典中的套接字是否对应,如消息主题与缓存字典SN存在包含关系,则认为此消息与网页端套接字存在关联关系,则将消息推送给此套接字。

具体实现代码:

static IMqttClient client;public static async void Client(){try{client = new MqttFactory().CreateMqttClient() as MqttClient;var build = new MqttClientOptionsBuilder().WithClientId(Guid.NewGuid().ToString().Replace("-", "").ToUpper()).WithCredentials("emqx_test", "emqx_test").WithTcpServer("broker.emqx.io", 1883).WithCleanSession(true).WithKeepAlivePeriod(TimeSpan.FromSeconds(100.5));client.ConnectedAsync += _mqttClient_ConnectedAsync;await client.ConnectAsync(build.Build());client.DisconnectedAsync += _mqttClient_DisconnectedAsync;client.ApplicationMessageReceivedAsync += _mqttClient_ApplicationMessageReceivedAsync;await client.SubscribeAsync(new MqttClientSubscribeOptions{TopicFilters = new List<MqttTopicFilter> {new MqttTopicFilter() //订阅消息对象{Topic = "123",  //订阅消息主题QualityOfServiceLevel = MqttQualityOfServiceLevel.AtLeastOnce  //消息类型},new MqttTopicFilter() //订阅消息对象{Topic = "12345",  //订阅消息主题QualityOfServiceLevel = MqttQualityOfServiceLevel.AtLeastOnce  //消息类型}}});}catch (Exception e){Console.WriteLine($"连接失败");}}private static Task _mqttClient_ApplicationMessageReceivedAsync(MqttApplicationMessageReceivedEventArgs arg){var msg = arg.ApplicationMessage.ConvertPayloadToString();foreach (var item in socketDic){if (item.Value!=null && arg.ApplicationMessage.Topic.Contains(item.Value)){item.Key.Send($"hello {item.Value},{msg}");}}Console.WriteLine(arg.ApplicationMessage.ConvertPayloadToString());return Task.FromResult("");}private static Task _mqttClient_DisconnectedAsync(MqttClientDisconnectedEventArgs arg){Console.WriteLine($"客户端“{client.Options.ClientId}”已断开MQTT服务器!");return Task.FromResult("");}private static Task _mqttClient_ConnectedAsync(MqttClientConnectedEventArgs arg){Console.WriteLine($"客户端“{client.Options.ClientId}”已连接MQTT服务器!");return Task.FromResult("");}

3、网页端实现

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head><title>websocket client</title><script type="text/javascript">var start = function () {var inc = document.getElementById('incomming');var wsImpl = window.WebSocket || window.MozWebSocket;var form = document.getElementById('sendForm');var input = document.getElementById('sendText');inc.innerHTML += "connecting to server ..<br/>";// create a new websocket and connectwindow.ws = new wsImpl('ws://localhost:8181/');// when data is comming from the server, this metod is calledws.onmessage = function (evt) {inc.innerHTML += evt.data + '<br/>';};// when the connection is established, this method is calledws.onopen = function () {inc.innerHTML += '.. connection open<br/>';ws.send("SN:12345");};// when the connection is closed, this method is calledws.onclose = function () {inc.innerHTML += '.. connection closed<br/>';}//form.addEventListener('submit', function(e){//	e.preventDefault();//	var val = input.value;//	ws.send(val);//	input.value = "";//}); }window.onload = start;</script>
</head>
<body><form id="sendForm"><input id="sendText" placeholder="Text to send" /></form><pre id="incomming"></pre>
</body>
</html>

4、测试

启动WebSocket服务器控制台应用程序;

运行MQTT.fx工具,新建连接

给12345主题发布消息,

观察网页端是否收到消息,

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

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

相关文章

第7章 排序

前言 在这一章&#xff0c;我们讨论数组元素的排序问题。为简单起见&#xff0c;假设在我们的例子中数组只包含整数&#xff0c;虽然更复杂的结构显然也是可能的。对于本章的大部分内容&#xff0c;我们还假设整个排序工作能够在主存中完成&#xff0c;因此&#xff0c;元素的个…

计算机网络知识点

计算机网络中的OSI模型 OSI模型是指“国际标准化组织(SO)”提出的使各种计算机在世界范围内互通互联的网络标准框架简称开放系统互联参考模型 (OSI)。 七层模型&#xff1a;应用层、表示层、会话层、传输层、网络层&#xff08;IP协议、RARP协议、ARP协议、CIDR协议&#xff0…

kafka学习笔记--Topic 数据的存储机制

本文内容来自尚硅谷B站公开教学视频&#xff0c;仅做个人总结、学习、复习使用&#xff0c;任何对此文章的引用&#xff0c;应当说明源出处为尚硅谷&#xff0c;不得用于商业用途。 如有侵权、联系速删 视频教程链接&#xff1a;【尚硅谷】Kafka3.x教程&#xff08;从入门到调优…

docker小白第五天

docker小白第五天 docker的私有库 有些涉密的信息代码不能放在阿里云的镜像仓库&#xff0c;因此需要构建一个个人内网专属的私有库&#xff0c;将镜像或者容器代码进行推送保存。 下载镜像docker registry 执行代码docker pull registry&#xff0c;用于搭建私服前的准备。…

Linux系统log日志简单清理

系统空间告急 清理log日志 找出当前目录中文件最大的10个文件&#xff1a; cd /var/log du -s ./* | sort -nr | head 系统日志log文件&#xff1a; ll -h /var/log/journal 只保留100MB的日志 journalctl --vacuum-size100M 系统暴力爆破SSH日志&#xff1a; ll -h /var/lo…

初级数据结构(六)——堆

文中代码源文件已上传&#xff1a;数据结构源码 <-上一篇 初级数据结构&#xff08;五&#xff09;——树和二叉树的概念 | NULL 下一篇-> 1、堆的特性 1.1、定义 堆结构属于完全二叉树的范畴&#xff0c;除了满足完全二叉树的限制之外&#xff0c;还满…

SolidWorks二次开发 C#-读取基于Excel的BOM表信息

SolidWorks二次开发 C#-读取基于Excel的BOM表信息 问题点来源解决方案及思路相关引用链接 问题点来源 这是一位粉丝问的一个问题&#xff0c;他说到: 老师&#xff0c;请问Solidworks二次开发工程图中"基于Excel的材料明细表"怎么读取里面的数据&#xff1f; Ps:这…

leetcode刷题日志-383赎金信

思路&#xff1a;分别用两个map记录ransomNote和magazine中的字符以及出现的次数。最后遍历记录ransomNote的map&#xff0c;如果ransomNote的map中出现的magazine的map中没有出现或者出现的次数小于ransomNote的map则返回false&#xff0c;否则返回true&#xff1b; class So…

arcgis api for js 图层标注文本不显示

在打包arcgis api for js 项目后&#xff0c;更新到现场所有地图文本要素不显示的时候。 可能就是环境设置问题了&#xff0c;需要配置iis或者ngixs里边配置如下类型 iis发布的项目 1、打开iis中发布的网站 2、找到网站的MIME类型如下图 3、添加一下类型&#xff08;一个都不…

机器学习项目精选 第一期:超完整数据科学资料合集

大噶吼&#xff0c;不说废话&#xff0c;分享一波我最近看过并觉得非常硬核的资源&#xff0c;包括Python、机器学习、深度学习、大模型等等。 1、超完整数据科学资料合集 地址&#xff1a;https://github.com/krishnaik06/The-Grand-Complete-Data-Science-Materials Pytho…

【Linux API 揭秘】container_of函数详解

我的圈子&#xff1a; 高级工程师聚集地 我是董哥&#xff0c;高级嵌入式软件开发工程师&#xff0c;从事嵌入式Linux驱动开发和系统开发&#xff0c;曾就职于世界500强企业&#xff01; 创作理念&#xff1a;专注分享高质量嵌入式文章&#xff0c;让大家读有所得&#xff01; …

1852_bash中的find应用扩展

Grey 全部学习内容汇总&#xff1a; https://github.com/GreyZhang/toolbox 1852_bash中的find应用扩展 find这个工具我用了好多年了&#xff0c;但是是不是真的会用呢&#xff1f;其实不然&#xff0c;否则也不会出现这种总结式的笔记。其实&#xff0c;注意部分小细节之后…

liunx之Samba服务器

环境&#xff1a;虚拟机CENTOS 7和 测试机相通 一、Samba服务器_光盘共享&#xff08;匿名访问&#xff09; 1.在虚拟机CENTOS 7安装smb服务&#xff0c;并在防火墙上允许samba流量通过 2. 挂载光盘 3.修改smb.conf配置文件&#xff0c;实现光盘匿名共享 4. 启动smb服务 5.在…

手麻、腿麻、麻痛…背后竟隐藏7大疾病!多一个人知道,少一个悲剧!

手脚麻木背后的7大病症&#xff1a;骨病、脑梗、肿瘤…… 1、神经问题 上图四只手上橙色的区域代表了麻木感&#xff0c;如果您的手麻集中在无名指和小指的区域&#xff0c;您可以拿一张纸&#xff0c;用五个手指分别试着夹住&#xff0c;检验您的五个手指力量&#xff1b;您还…

(5)shell命令以及Linux的权限

写在前面 本章我们将重点讲解 Linux 权限&#xff0c;这是 Linux 基础部分中非常重要的一部分。内容比较干&#xff0c;我会稍稍正经些去讲解。话不多说&#xff0c;我们直接切入正题。 shell 命令及运行原理 严格意义上说的是一个操作系统&#xff0c;我们称之为 —— &…

Logstash访问安全访问Elasticsearch集群

生成logstash证书: opensal pkcs12 -in elastic-stack-ca.p12 -clcerts -nokeys > logafash.cer openssl x509 -in logstash.cer -out logstash.pem 编排配置文件

xtu oj 1328 数码和

题目描述 一个10进制数n在2∼16进制下可以得到的不同的数码和&#xff0c;求在这些数码和中出现次数最多的数码和。 比如20&#xff0c; 其中数码和2和4分别出现了3次&#xff0c;为最多出现次数。 输入 第一行是一个整数T(1≤T≤1000)&#xff0c;表示样例的个数。 以后每行…

Sherlock:社交媒体账号搜索工具 | 开源日报 No.111

sherlock-project/sherlock Stars: 45.1k License: MIT 这个项目是一个社交媒体账号搜索工具&#xff0c;名为 Sherlock。它可以通过用户名在不同的社交网络上追踪用户的账号。 支持单个或多个用户搜索提供 Docker 容器化部署方式开放源代码并欢迎贡献者参与开发包含详细测试…

Shell三剑客:sed(命令)一

一、删除命令&#xff1a;d [rootlocalhost ~]# sed -r /root/d passwd.txt bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin sync:x:5:0:sync:/sbin:/bin/sync…

Vim入门

Vim使用入门 1.Vim编辑器的三种常用模式 一般模式&#xff1a;刚打开文件是它&#xff0c;从编辑模式按“ESC”退回的模式也是它。可以执行各种编辑操作&#xff0c;如移动光标、复制、粘贴、删除、查找替换等 ; 编辑模式&#xff1a;在一般模式下按下 i、I、a、A、o、O 等键…