mm_os
Version:
这是超级美眉服务端框架,用于快速构建应用程序。
315 lines (288 loc) • 7.14 kB
JavaScript
require('./lib.js');
const mosca = require('mosca');
/**
* mqtt 物联网通讯类
*/
class MQTT {
/**
* 构造函数
* @param {Object} config 配置参数
*/
constructor(config) {
/**
* 配置参数
*/
this.config = Object.assign({
"state": true,
// mqtt访问端口号
"socket_port": 1883,
// 服务端
"http_host": "localhost",
// websocket 访问端口
"http_port": 8083,
// 缓存方式
"cache": "mongodb", // "mongodb",
redis: {
host: "localhost",
port: 6379,
password: "asd159357",
db: 12
},
mongodb: {
user: "",
password: "",
host: "localhost",
port: 27017,
database: "mqtt"
}
}, config);
/**
* MQTT服务器
*/
this.server = null;
this.list = [];
}
}
/**
* 客户端连接成功
* @param {Object} client 客户端信息
*/
MQTT.prototype.connected = async function(client) {
//监听连接
console.info('client connected', client.id);
return true;
}
/**
* 初始化
* @param {Object} config
*/
MQTT.prototype.init = function(config) {
if (config) {
this.config = Object.assign(this.config, config);
}
var cg = Object.assign({}, this.config);
var {
redis,
mongodb
} = cg;
var conf = {
port: cg.socket_port,
http: {
host: cg.http_host || "localhost",
port: cg.http_port,
bundle: true,
static: './'
}
}
if (cg.cache === 'redis') {
if (cg.redis) {
conf.backend = {
type: "redis",
redis: require('redis'),
host: redis.host || "localhost",
port: redis.port || 6379,
password: redis.password,
db: redis.db || 12,
return_buffers: true
}
} else {
conf.backend = {
type: "redis",
redis: require('redis'),
host: "localhost",
password: "asd159357",
port: 6379,
db: 12,
return_buffers: true
}
}
// 数据持久化参数设置
conf.persistence = Object.assign({
factory: mosca.persistence.Redis,
ttl: {
// TTL for subscriptions is 23 hour
subscriptions: 23 * 60 * 60 * 1000,
// TTL for packets is 23 hour
packets: 23 * 60 * 60 * 1000,
}
}, conf.backend);
} else if (cg.cache === 'mongodb' || cg.cache === 'mongo') {
var url = `mongodb://${mongodb.host}:${mongodb.port}/${mongodb.database}`;
if (mongodb.user) {
url =
`mongodb://${mongodb.user}:${mongodb.password}@${mongodb.host}:${mongodb.port}/${mongodb.database}`
}
conf.backend = {
// 增加了此项
type: 'mongo',
url,
pubsubCollection: 'ascoltatori',
mongo: {}
}
// 数据持久化参数设置
conf.persistence = Object.assign({
factory: mosca.persistence.Mongo,
ttl: {
// TTL for subscriptions is 23 hour
subscriptions: 23 * 60 * 60 * 1000,
// TTL for packets is 23 hour
packets: 23 * 60 * 60 * 1000,
}
}, conf.backend);
}
this.server = new mosca.Server(conf);
return this;
};
/**
* 引用
* @param {Function} 函数
*/
MQTT.prototype.use = function(func) {
// this.server.use(func);
};
/**
* 运行主程序
* @param {String} state 状态
*/
MQTT.prototype.main = function(state) {
var cg = this.config;
sr = this.server;
var _this = this;
/**
* 对服务器端口进行配置,在此端口进行监听
* @param {Object} client 客户端信息
*/
sr.on('clientConnected', async function(client) {
return await _this.connected(client);
});
/**
* 监听MQTT主题消息
* @param {Object} packet 订阅消息
* @param {Object} client 客户端信息
*/
sr.on('published', function(packet, client) {
_this.published(packet, client);
});
/**
* 监听MQTT主题消息
* @param {String} topic 订阅主题
* @param {Object} client 客户端信息
*/
sr.on('subscribed', function(topic, client) {
_this.subscribed(topic, client);
});
/**
* 身份验证
*/
sr.authenticate = (client, username, password, callback) => {
$.log.info("收到身份验证", username, password);
this.auth(client, username, password, callback);
return true;
};
/**
* 验证发布,决定客户端可以发布哪些主题
*/
sr.authorizePublish = (client, topic, payload, callback) => {
this.authPublish(client, topic, payload, callback);
return true;
};
/**
* 验证订阅,决定客户端可以订阅哪些主题
*/
sr.authorizeSubscribe = (client, topic, callback) => {
this.authSubscribe(client, topic, callback);
return true;
};
/**
* 当服务开启时
*/
sr.on('ready', function() {
// 当服务开启时
console.info(`MQTT访问 mqtt://127.0.0.1:${cg.socket_port} || ws://127.0.0.1:${cg.http_port}`);
});
}
/**
* 收到订阅时
* @param {String} topic 订阅主题
* @param {Object} client 客户端信息
*/
MQTT.prototype.subscribed = function(topic, client) {
// console.log("订阅", topic, client.id);
};
/**
* 收到推送消息时
* @param {Object} packet 订阅的消息
* @param {Object} client 客户端信息
*/
MQTT.prototype.published = function(packet, client) {
// console.log("发布", packet.topic, packet.payload.toString());
};
/**
* 身份验证
* @param {Object} client 客户端
* @param {String} username 用户名
* @param {String} password 密码
* @param {Function} callback 回调函数,回调返回true,则表示验证通过。
*/
MQTT.prototype.auth = function(client, username, password, callback) {
// console.log("连接授权", client.id, username, password ? password.toString() : '');
var bl = true;
// 回调第二个参数为true表示验证通过, 为false表示验证失败
callback(null, bl);
};
/**
* 验证发布,决定客户端可以发布哪些主题
* @param {Object} client 客户端
* @param {String} topic 用户名
* @param {Object} payload 参数
* @param {Function} callback 回调函数,回调返回true,则表示验证通过。
*/
MQTT.prototype.authPublish = function(client, topic, payload, callback) {
var bl = true;
// if(topic == "temperature"){
// bl = false;
// }
// console.log('收到推送', client.id, topic, payload.toString());
// 回调第二个参数为true表示验证通过, 为false表示验证失败
callback(null, bl);
};
/**
* 验证订阅,决定客户端可以订阅哪些主题
* @param {Object} client 客户端
* @param {String} topic 用户名
* @param {Function} callback 回调函数,回调返回true,则表示验证通过。
*/
MQTT.prototype.authSubscribe = function(client, topic, callback) {
var bl = true;
// 回调第二个参数为true表示验证通过, 为false表示验证失败
callback(null, bl);
};
/**
* 运行主程序前
* @param {String} state 状态
*/
MQTT.prototype.before = async function(state) {
var list = this.list;
for (var i = 0; i < list.length; i++) {
var o = list[i];
o.func = require(o.func_file);
if (o.func) {
o.func(this.server, this.config);
}
}
};
/**
* 运行主程序后
* @param {String} state 状态
*/
MQTT.prototype.after = async function(state) {};
/**
* 运行
* @param {String} state 状态
*/
MQTT.prototype.run = async function(state = 'start') {
await this.before(state);
await this.main(state);
await this.after(state);
};
module.exports = MQTT;