客户打算把聊天内容发送到php server
php server 接收消息并进行相关业务处理,然后publish到redis
node js 作为mqtt 的broker 订阅redis
aedes可以在任何流服务器上运行的准系统 MQTT 服务器
$ npm init -y
$ npm install aedes
$ npm install mqemitter-redis --save
新建index.js文件
var http = require('http')
var websocket = require('websocket-stream')
require('events').EventEmitter.defaultMaxListeners = 0
var mq = require('mqemitter-redis')({
port: '6379',
host: '127.0.0.1',
password: '123456',
db: 2
})
var aedes = require('aedes')({
concurrency: 666,
mq: mq
})
// 身份验证
aedes.authenticate = function (client, username, password, callback) {
callback(null, (username === 'user' && password.toString() === '123456'));
}
//禁止pub
aedes.authorizePublish = function(client, packet, callback) {
callback(new Error('no publish'));
};
//sub消息
aedes.authorizeSubscribe = function (client, sub, callback) {
if (sub.topic === 'aaaa') {
return callback(new Error('wrong topic'))
}
if (sub.topic === 'bbb') {
// overwrites subscription
sub.topic = 'foo'
sub.qos = 1
}
callback(null, sub)
}
var server = require('net').createServer(aedes.handle)
server.listen(7888, function () {
console.log('===server listening on port===', 1883)
})
var httpServ = http.createServer()
websocket.createServer({server: httpServ, port: 1884}, aedes.handle)
我们根据mqemitter-redis 拼装redis publish数据结构
mqemitter-redis.js
function handler (sub, topic, payload) {
var packet = msgpack.decode(payload)
//console.log("packet:"+packet.id)
if(that.redisCache.set("p:"+packet.id, 1, "EX", 10, "NX")){
//console.log("packet:"+packet.id+":ok")
that._emit(packet.msg)
}
}
根据以上代码我们可以得到
{
cmd: 'publish',
messageId: 42,
qos: 1,
dup: false,
topic: 'test',
payload: new Buffer('test'),
retain: false,
properties: { // optional properties MQTT 5.0
payloadFormatIndicator: true,
messageExpiryInterval: 4321,
topicAlias: 100,
responseTopic: 'topic',
correlationData: Buffer.from([1, 2, 3, 4]),
userProperties: {
'test': 'test'
},
subscriptionIdentifier: 120, // can be an Array in message from broker, if message included in few another subscriptions
contentType: 'test'
}
}
php server 代码
server.php
public function send($topic, $content){
$message = [];
$message['id'] = uuid();
$message['msg'] = [];
$message['msg']['cmd'] = 'publish';
$message['msg']['retain'] = false;
$message['msg']['qos'] = 2;
$message['msg']['topic'] = $topic;
$message['msg']['payload'] = $content;
$message['msg']['messageId'] = uuid();
//$message['msg']['properties'] = ['messageExpiryInterval':125]; //optional properties
//发布消息
(\Redis ())->publish($topic, msgpack_pack($message));
}
$this->send('test','我就测试下');
$this->send('bbb','我就测试下');
把server.php 改成接收api 传递消息
前段监听1884端口
到此整个用MQTT 实现聊天功能的架构就完成了