网页端HTML使用MQTTJs订阅RabbitMQ数据
<script type="text/javascript" src="~/js/MqJs/jquery.js"></script>
<script type="text/javascript" src="~/js/MqJs/browserMqtt.min.js"></script>
<script type="text/javascript" src="~/js/MqJs/mqfactory.js"></script>
<body>
<div>
<lable>Host: </lable><input id="txtHost" placeholder="192.168.1.88" value="10.1.0.7" /><br />
<lable>Port: </lable><input id="txtPort" placeholder="15675" value="15675" /><br />
<label>UserName: </label><input id="txtUserName" placeholder="username" value="admin" /><br />
<label>Password: </label><input id="txtPassword" placeholder="password" value="admin" /><br />
<label>Protocol: </label><input id="txtProtocol" placeholder="ws" value="ws" /><br />
<input id="btnConnect" type="button" value="Connect RabbitMQ" />
</div>
<div>
<input id="btnSubscribe" type="button" value="Subscribe" />
<input id="btnPublish" type="button" value="Publish" /><br />
<input id="btnSSHuanjing" type="button" value="Subscribe Huanjing" />
<input id="hdnIsSubscribed" type="hidden" value="" />
<input id="btnPubHuanjing" type="button" value="Publish Huanjing"><br />
路由:<input id="btnRoutingKey" type="text" value="Dcon/Logs/Client"><br />
<input id="txtMessage" type="text" placeholder="Please enter message" />
</div>
<div>
<label>log:</label><br />
<ul id="lstLog"></ul>
<input id="btnClearLog" type="button" value="Clear Log" />
</div>
</body>
<script type="text/javascript">
$(function () {
var mqclient;
//var routingKey = 'Dcon.Logs.ServerWebShow';
var message; $('#btnSubscribe').attr('disabled', 'disabled');
$('#btnPublish').attr('disabled', 'disabled');
$('#btnSSHuanjing').attr('disabled', 'disabled');
$('#btnPubHuanjing').attr('disabled', 'disabled'); $('#btnConnect').click(function () {
var mqttOpts = {
host: (() => $('#txtHost').val())(),
port: (() => $('#txtPort').val())(),
username: (() => $('#txtUserName').val())(),
password: (() => $('#txtPassword').val())(),
//transformWsUrl方法用于在浏览器中使用MQTT的场景,默认情况下,MQTT自动生成的url为ws://ip:port形式,
//然而服务器要求的格式是ws://ip:port/ws,所以MQTT提供了此接口用于在生成url时自定义url格式
transformWsUrl: (url, opts, client) => { return opts.protocol && opts.protocol == 'ws' ? url + 'ws' : url; },
clientId: (() => { return 'mqttjs_' + Math.random().toString(16).substr(2, 8); })()
};
var biz = {
huanjing: function (handler, isOn) {
if (isOn !== false) {
this.ss(this.topics.huanjing, handler);
} else {
this.sus(this.topics.huanjing, handler);
}
},
topics: {
huanjing: '/hyj/huanjing/monitor'
}
};
//系统初始化时注入连接选项
mqfactory.inject(mqttOpts, biz);
//创建mqclient单例
mqclient = mqfactory.create();
//注册mqclient的连接成功事件
mqclient.on('connect', mqconnected);
}); $('#btnSubscribe').click(function () {
if ($(this).val() == 'Subscribe') {
//订阅成功后,仅注册一次事件(要考虑每次注册事件时,事件处理器调用的次数,如果仅用一次,就用once方法)
//routingKey = $("#btnRoutingKey").val();
mqclient.once('onss', mqSubscribeSuccess);
//简单订阅
mqclient.ss($("#btnRoutingKey").val());
} else {
mqclient.once('onsus', mqUnsubscribeSuccess)
mqclient.sus($("#btnRoutingKey").val());
}
}); $('#btnPublish').click(function () {
var msg = $('#txtMessage').val().length > 0 ? $('#txtMessage').val() : guid();
if (message === msg) {
msg = guid();
}
message = msg;
$('#txtMessage').val(message);
//发送消息
mqclient.pub($("#btnRoutingKey").val(), message);
$('#lstLog').append('<li>Send Message: ' + message + '</li>');
}); $('#btnSSHuanjing').click(function () {
if ($(this).val() == 'Subscribe Huanjing') {
mqclient.once('onss', mqHJSubscribeSuccess);
mqclient.huanjing(onHuanjingMessageArrived);
} else {
mqclient.once('onsus', mqHJUnsubscribeSuccess);
mqclient.huanjing(onHuanjingMessageArrived, false);
}
}); $('#btnPubHuanjing').click(function () {
var msg = $('#txtMessage').val().length > 0 ? $('#txtMessage').val() : guid();
if (message === msg) {
msg = guid();
}
message = msg;
$('#txtMessage').val(message);
//发送消息
mqclient.pub(mqclient.topics.huanjing, message);
$('#lstLog').append('<li>Send Huanjing Message: ' + message + '</li>');
}); $('#btnClearLog').click(function () {
$('#lstLog').empty();
}); function mqconnected() {
//alert("mqconnected");
$('#btnSubscribe').removeAttr('disabled');
$('#btnPublish').removeAttr('disabled');
$('#btnSSHuanjing').removeAttr('disabled');
$('#btnPubHuanjing').removeAttr('disabled');
$('#lstLog').append('<li>mqclient connected</li>');
} function mqSubscribeSuccess() {
//订阅成功,就注册接受消息的方法,此处要接收多次,因此使用了on
mqclient.on($("#btnRoutingKey").val(), onMessageArrived);
$('#btnSubscribe').val('Unsubscribe');
$('#lstLog').append('<li>Subscribe successful.' + $("#btnRoutingKey").val()+'</li>');
} function mqUnsubscribeSuccess() {
//注销订阅,所以将事件处理器解除绑定
mqclient.off($("#btnRoutingKey").val(), onMessageArrived);
$('#btnSubscribe').val('Subscribe');
$('#lstLog').append('<li>Unsubscribe successful</li>');
} function mqHJSubscribeSuccess() {
$('#btnSSHuanjing').val('Unsubscribe Huanjing');
$('#lstLog').append('<li>Hanjing Subscribe successful</li>');
} function mqHJUnsubscribeSuccess() {
$('#btnSSHuanjing').val('Subscribe Huanjing');
$('#lstLog').append('<li>Huanjing Unsubscribe successful</li>');
} function onMessageArrived(message) {
$('#lstLog').append('<li>Receive message: ' + new Date().toString() + ' ' + message.toString() + '</li>');
} function onHuanjingMessageArrived(message) {
$('#lstLog').append('<li>Receive Huanjing message: ' + new Date().toString() + ' ' + message.toString() + '</li>');
} function guid() {
function s4() {
return Math.floor((1 + Math.random()) * 0x10000)
.toString(16)
.substring(1);
}
return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
s4() + '-' + s4() + s4() + s4();
}
});
</script>
/// <summary>
/// 写日志
/// </summary>
/// <param name="model"></param>
public static void Write(LogModel model)
{
//判断写入的日志级别
if (model != null && model.LogLevel >= LogLevel)
{
try
{
var mqMsg = new MqMessage()
{
MessageBody = JSON.Serialize(model),
MessageRouter = SystemConst.RoutingKeyTopic.LogTopic_Producer
};
//MQHelper.Instance.ProducerMessage_Fanout(mqMsg);
MQHelper.Instance.ProducerMessage_Topic(mqMsg);
}
catch (Exception ex)
{
var errorLog = string.Format("Ip:{0},LogHelper.Write方法异常,{1}", IpHelper.LocalHostIp, ex.Message);
//MQHelper.Instance.ProducerMessage_Fanout(new MqMessage() { MessageBody = errorLog });
MQHelper.Instance.ProducerMessage_Topic(new MqMessage() { MessageBody = errorLog });
}
}
}
3.2后端MQ代码:
#region 主题 交换机
/// <summary>
/// 生产者 客户端调用
/// </summary>
/// <param name="msg"></param>
public void ProducerMessage_Topic(MqMessage msg)
{
try
{
using (var connection = factory.CreateConnection())
{
using (var channel = connection.CreateModel())
{
var body = Encoding.UTF8.GetBytes(msg.MessageBody);
channel.BasicPublish(exchange: SystemConst.MqName_LogMq_TopicDefault,
routingKey: msg.MessageRouter,
basicProperties: null,
body: body);
Console.WriteLine(" [x] Sent {0}", msg.MessageBody);
}
}
}
catch (Exception ex)
{
var exMsg = ex.Message;
}
} /// <summary>
/// 消费者 服务器接收并写入数据库
/// 消费方法无法通过参数传入
/// EventHandler<BasicDeliverEventArgs> received
/// </summary>
public void ConsumeMessage_Topic(params string[] routingKeys)
{
if (routingKeys == null || routingKeys.Length == )
{
throw new Exception("请指定接收路由");
}
using (var connection = factory.CreateConnection())
{
using (var channel = connection.CreateModel())
{
var queueName = channel.QueueDeclare().QueueName;//获得已经生成的随机队列名
//对列与交换机绑定
foreach (var rKey in routingKeys)
{
channel.QueueBind(queue: queueName,
exchange: SystemConst.MqName_LogMq_TopicDefault,
routingKey: rKey);
} var consumer = new EventingBasicConsumer(channel);
//绑定消费方法
consumer.Received += consomer_Received_Topic;
//绑定消费者
channel.BasicConsume(queue: queueName,
autoAck: true,
consumer: consumer);
Console.WriteLine("日志订阅服务启动成功.");
Console.WriteLine(" Press [enter] to exit.");
Console.ReadLine();
}
}
} /// <summary>
/// 接收通知服务异步的推送
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void consomer_Received_Topic(object sender, BasicDeliverEventArgs e)
{
var body = e.Body;
var message = Encoding.UTF8.GetString(body);
Console.WriteLine(" [x] {0}", message);
//这里可以增加写入数据库的代码
}
#endregion
3.3路由
/// <summary>
/// 主题路由
/// </summary>
public class RoutingKeyTopic
{
/// <summary>
/// 生产者
/// </summary>
public const string LogTopic_Producer = "Dcon.Logs.Client"; /// <summary>
/// 消息者_日志服务_保存日志
/// </summary>
public const string LogTopic_Consume_Server_SaveDB = "Dcon.Logs.*"; /// <summary>
/// 消息者_日志服务_Web显示日志
/// </summary>
public const string LogTopic_Consume_Server_WebShow = "Dcon.Logs#";//".Logs.Client"; /// <summary>
/// 消息者_日志服务_Web显示日志
/// </summary>
public const string LogTopic_Consume_Server_WebShow_T = "*.Logs.Client";//".Logs.Client"; /// <summary>
/// 消息者_日志服务_ # 接收所有
/// </summary>
public const string LogTopic_Consume_Server_All = "#";//".Logs.Client";
}
}

网页端HTML使用MQTTJs订阅RabbitMQ数据的更多相关文章
- 吉特仓库管理系统(开源)-如何在网页端启动WinForm 程序
在逛淘宝或者使用QQ相关的产品的时候,比如淘宝我要联系店家点击旺旺图标的时候能够自动启动阿里旺旺进行聊天.之前很奇怪为什么网页端能够自动启动客户端程序,最近在开发吉特仓储管理系统的时候也遇到一个类似的 ...
- 如何在网页端启动WinForm 程序
在逛淘宝或者使用QQ相关的产品的时候,比如淘宝我要联系店家点击旺旺图标的时候能够自动启动阿里旺旺进行聊天.之前很奇怪为什么网页端能够自动启动客户端程序,最近在开发吉特仓储管理系统的时候也遇到一个类似的 ...
- 应用市场高速下载以及网页端调起APP页面研究与实现
Github博文地址,此处更新可能不是很及时. 好久没写博客了,好大一个坑.正好,最近刚做完应用市场的高速下载功能,便拿来填了这个坑. 话说产品为了增加用户量,提升用户活跃度以及配合推广,更坑爹的是看 ...
- 网页端启动WinForm
网页端启动WinForm 程序 在逛淘宝或者使用QQ相关的产品的时候,比如淘宝我要联系店家点击旺旺图标的时候能够自动启动阿里旺旺进行聊天.之前很奇怪为什么网页端能够自动启动客户端程序,最近在开发吉特仓 ...
- 分享基于 websocket 网页端聊天室
博客地址:https://ainyi.com/67 有一个月没有写博客了,也是因为年前需求多.回家过春节的原因,现在返回北京的第二天,想想,应该也要分享技术专题的博客了!! 主题 基于 websock ...
- 应用市场快速下载以及网页端调起APP页面研究与实现
Github博文地址,此处更新可能不是非常及时. 好久没写博客了,好大一个坑. 正好,近期刚做完应用市场的快速下载功能,便拿来填了这个坑. 话说产品为了添加用户量,提升用户活跃度以及配合推广,更坑爹的 ...
- 【Beta】“北航社团帮”测试报告——小程序v2.0与网页端v1.0
目录 测试计划.过程和结果 后端测试--单元测试与覆盖率 后端测试--压力测试 展示部分数据 平均数据 前端测试--小程序v2.0 授权登录与权限检查 新功能的测试 兼容性测试 性能测试 前端测试-- ...
- 【Beta】“北航社团帮”发布声明——小程序v2.0与网页端v1.0
目录 Beta版本新功能 小程序v2.0新功能 新功能列表 功能详情图 新功能动图展示 网页端v1.0功能 登录方式 社团信息的修改 新闻的录入和修改 活动的录入和修改 这一版修复的缺陷 Beta版本 ...
- 转载:微信开放平台开发第三方授权登陆(二):PC网页端
微信开放平台开发第三方授权登陆(二):PC网页端 2018年07月24日 15:13:32 晋文子上 阅读数 12644更多 分类专栏: 微信开发 第三方授权登录 版权声明:本文为博主原创文章,遵 ...
随机推荐
- Akka(20): Stream:压力缓冲-Batching backpressure and buffering
akka-stream原则上是一种推式(push-model)的数据流.push-model和pull-model的区别在于它们解决问题倾向性:push模式面向高效的数据流下游(fast-downst ...
- C#打印九九乘法表
C#打印九九乘法表... ---------------------------------- using System; using System.Collections.Generic; usin ...
- b64_md5加密Java、JavaScript实现
问题说明 MD5的作用是让大容量信息在用数字签名软件签署私人密钥前被"压缩"成一种保密的格式(就是把一个任意长度的字节串变换成一定长的十六进制数字串).经过md5后的字符数组中含有 ...
- poj2912 Rochambeau
Description N children are playing Rochambeau (scissors-rock-cloth) game with you. One of them is th ...
- GCC和G++区别
原文:http://www.cnblogs.com/samewang/p/4774180.html 看的Linux公社的一篇文章,觉得不错,内容复制过来了. 其实在这之前,我一直以为gcc和g++是一 ...
- DOM树节点和事件
一.前言:DOM树节点是JS的基础语句.通过节点,能够取到HTML代码中的任意标签,从而对其进行修改和添加各种视觉效果. 二.DOM树节点 DOM节点分为三大类: 元素节点,属性节点,文本节点 ...
- 优化关键渲染路径CRP
什么是关键渲染路径? 从收到 HTML.CSS 和 JavaScript 字节到对其进行必需的处理,从而将它们转变成渲染的像素这一过程中有一些中间步骤 浏览器渲染页面前需要先构建 DOM 和 CSSO ...
- Spark 1.6升级2.x防踩坑指南
原创文章,谢绝转载 Spark 2.x自2.0.0发布到目前的2.2.0已经有一年多的时间了,2.x宣称有诸多的性能改进,相信不少使用Spark的同学还停留在1.6.x或者更低的版本上,没有升级到2. ...
- zbrush曲面增加厚度
把曲面增加厚度方便雕刻机雕刻. 可以使用zbrush中的边循环功能. 1.准备好需要增加厚度的曲面,把曲面的边缘调整好,尽量的变得平滑. 2.将模型导入到zbrush中,开启双面显示,以方便观察模型的 ...
- CCIE-交换路由复习笔记
交换 考点: 1.trunk link(基础) 2.vtp 3.vlan 4.stp rstp mstp 5.hsrp vrrp glbp 6.ec Trunk link: 修改封装模式 802.1q ...