Javascript 如何将消息从mosca代理发送到mqtt.js客户端
我们设置了一个由供电的MQTT客户机(在台式PC上或在实际板上,两者相同)和一个由供电的MQTT代理,这一个运行在台式PC上 我们能够成功地将带有特定主题的消息从客户端发送到代理,但现在我们却陷入了相反的境地:将消息从代理发送到客户端 我们正在遵循两个项目文档中提供的代码示例,但运气不佳。客户端能够正确注册到主题,但在发送消息时不会做出任何反应。代理能够正确地发送消息,也能够侦听自己的消息,因为它正在侦听所有消息 摘自MQTT broker:Javascript 如何将消息从mosca代理发送到mqtt.js客户端,javascript,mqtt,iot,Javascript,Mqtt,Iot,我们设置了一个由供电的MQTT客户机(在台式PC上或在实际板上,两者相同)和一个由供电的MQTT代理,这一个运行在台式PC上 我们能够成功地将带有特定主题的消息从客户端发送到代理,但现在我们却陷入了相反的境地:将消息从代理发送到客户端 我们正在遵循两个项目文档中提供的代码示例,但运气不佳。客户端能够正确注册到主题,但在发送消息时不会做出任何反应。代理能够正确地发送消息,也能够侦听自己的消息,因为它正在侦听所有消息 摘自MQTT broker: broker.on('published', fun
broker.on('published', function(packet, client) {
console.log('MQTT broker received message'); // it passes by here
console.log(' - packet:', packet);
console.log(' - packet payload:', packet.payload.toString());
});
// ...
var packet = {
topic: 'our_custom_topic',
payload: ourCustomPayload,
qos: 1,
retain: false,
};
console.log('MQTT broker sending message to client ...');
broker.publish(packet, function() {
console.log('Message sent'); // it passes by here
});
摘自MQTT客户机:
client.on('connect', function () {
console.log('MQTT client connected');
client.subscribe('our_custom_topic', { qos: 1 }, function onSubscribe(err, granted) {
if (err) {
console.log('subscribe errors:', err); // no error shown
}
if (granted) {
console.log('subscribe granted:', granted); // it passes by here
}
});
});
// ...
client.on('message', function (topic, message, packet) {
console.log('MQTT client received message'); // it DOESN'T pass by here
console.log(' - topic', topic);
console.log(' - message', JSON.stringify(message));
console.log(' - packet', JSON.stringify(packet));
});
更新
当持久性基于mongoDb时,问题似乎就出现了。相反,当持久性基于内存时,消息会正确地发送给订阅者。以下是我们在依赖mongoDb持久性时的发布订阅设置。实际上,它是一个运行在mongolab.com上的开发实例:
var mongoDbSettings = {
// remote MongoLab mongodb instance
url: 'mongodb://mqtt-db-user:<OUR-USER-CODE>@<THEIR-INSTANCE-SUBDOMAIN>.mongolab.com:39291/sample-mqtt-datastore',
pubsubCollection: 'myCollections',
};
var mongoDbBrokerSettings = {
port: 1883, // mosca (mqtt) port
// using ascoltatore over MongoDB
backend: {
type: 'mongo',
url: mongoDbSettings.url,
pubsubCollection: mongoDbSettings.pubsubCollection,
mongo: {},
},
persistence: {
factory: mosca.persistence.Mongo,
url: mongoDbSettings.url,
}
};
var broker = new mosca.Server(mongoDbBrokerSettings, function onCreated(err, broker) {
// assume no errors
console.log('MQTT broker is up and running');
});
var mongoDbSettings={
//远程mongodb mongodb实例
网址:'mongodb://mqtt-db-user:@.mongolab.com:39291/sample mqtt datastore',
pubsubCollection:“myCollections”,
};
var mongoDbBrokerSettings={
端口:1883,//mosca(mqtt)端口
//在MongoDB上使用ascoltatore
后端:{
键入:“mongo”,
url:mongoDbSettings.url,
pubsubCollection:mongoDbSettings.pubsubCollection,
蒙戈:{},
},
持久性:{
工厂:mosca.persistence.Mongo,
url:mongoDbSettings.url,
}
};
var broker=new mosca.Server(mongoDbBrokerSettings,函数onCreated(err,broker){
//假设没有错误
log(“MQTT代理已启动并正在运行”);
});
有人发现这有什么问题吗?MQTT代理处理客户机之间的消息,但不发送它们(最后遗嘱特殊消息除外) 您必须实现以下功能:
- 客户端A订阅一个主题:test/one
- 客户端B将消息发布到同一主题:test/one
- 自动订阅此主题的所有客户端(如客户端A)都将收到消息
我们的自定义\u主题
的外部客户端(如mosquito\u sub或MQTT.fx)有效发布
持久性不应影响消息的发布,但您可以安装MOSQUITO并测试是否将其用作后端工程您可以直接从代理发布,因为它是Mosca公共API的一部分:
/**
* Publishes a packet on the MQTT broker.
*
* @api public
* @param {Object} packet The MQTT packet, it should include the
* topic, payload, qos, and retain keys.
* @param {Object} client The client object (internal)
* @param {Function} callback The callback
*/
Server.prototype.publish = function publish(packet, client, callback)...
只要您的客户机已订阅,您就可以通过
broker.publish({topic:/foo/bar,payload:'foo'},client)
在您要发送的模型实例的客户机上(即通过回调)发送。我们修补了一些调试日志,显然它的\u handlePublish
方法甚至没有被调用,因此,实际上无法触发任何'message'
事件。仍在调查…在client.js链上,当代理发送消息时,甚至没有调用进程中的\u handlePacket
方法。查看mosca端,我们向添加了一些调试日志,可以看到调用了发布
方法,以及.published
回调的内部方法,在某个时刻,我们看到了某种异常或错误消息,导致客户端自行断开连接并重新连接,但在服务器端没有报告任何问题。Error was参数必须是publish
中的字符串,位于…\mqtt connection\node\u modules\mqtt packet\generate.js:227:22
我们提供了一个示例测试,其中一个服务器发布了一个主题,一个客户端订阅了该主题:除了服务器创建的回调调用了两次之外,该方法有效。在实际项目中,MQTT代理也是一个express+socket.io web服务器,当然位于不同的端口上。不知道这是否是问题的根本原因谢谢你的反馈。是的,这是一种“经典的”——可以这么说——工作方式,但API似乎也支持服务器发送消息,我们没有发现任何不应该这样做的提及。在我们的上下文中,该场景非常有用。MQTT.js只是node.js的MQTT客户机实现。您需要为node.js运行类似mosca的代理吗?我认为这实际上就是我在开始时描述的场景:一个由MQTT.js支持的MQTT客户机,一个由mosca支持的MQTT代理,每个代理都运行在node.jsBrokers上处理消息。客户端通过连接到代理并订阅主题来获取消息,或者通过连接到代理并发布到主题来发送消息。代理无法发送消息,客户端连接到代理,是。“代理无法发送消息,客户端连接到代理,是。”在mosca API或文档中,这在哪里被阻止?我知道常规行为,但正如我所说的,在代理实现中似乎没有什么不符合的,即代理可以发送消息。如果您查看问题和代码示例,这实际上就是我们试图做的。它适用于基于内存的持久性,而不适用于基于mongodb的持久性(mongodb运行在mongolab.com上),您的意思是存储和访问客户机对象吗?上述解决方案不应该使用mqtt配置的后端。该值应相对于用户或设备或您的模型名进行存储。对不起,我的错,我不明白。我们的客户订阅了我们的自定义主题。Broker准备一个包含该主题的数据包并发布它。客户机应该接收并对其作出反应,但它的行为表现为什么都没有发生。如果服务器配置了内存内持久性,则相同的代码位(服务器和客户机)保持不变,如果服务器配置了mongodb持久性,则停止工作。由于其他原因,需要进行持久性配置(例如guar