成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

在Node.js下運(yùn)用MQTT協(xié)議實(shí)現(xiàn)即時(shí)通訊及離線推送

jlanglang / 2974人閱讀

摘要:前言前些日子了解到這樣一個(gè)協(xié)議,可以在上達(dá)到即時(shí)通訊的效果,但網(wǎng)上并不能很方便地找到一篇目前版本的在下正確實(shí)現(xiàn)這個(gè)協(xié)議的博客。

前言

前些日子了解到mqtt這樣一個(gè)協(xié)議,可以在web上達(dá)到即時(shí)通訊的效果,但網(wǎng)上并不能很方便地找到一篇目前版本的在node下正確實(shí)現(xiàn)這個(gè)協(xié)議的博客。

自己搗鼓了一段時(shí)間,理解不深刻,但也算是基本能夠達(dá)到使用目的。

本文目的為對(duì)MQTT有需求的學(xué)習(xí)者提供一定程度上的便利,省去了查閱官方文檔及源碼的功夫,但尚未對(duì)離線消息的接收順序進(jìn)行處理。

代碼

服務(wù)端: server.js

//服務(wù)端引入中間件mosca
let mosca = require("mosca")
let settings = {
  port: 5112
}
let server = new mosca.Server(settings)
server.on("ready", function(){
    console.log("Mosca server is up and running at port 5112");  
})
server.on("published", function(packet, client) {
  console.log("Published", packet.payload)
})

server.on("clientDisconnected", function(client){
  console.log("disconnected: ", client.id)
})

推送端: pub.js

//客戶端引入mqtt
let mqtt = require("mqtt");

let client = mqtt.connect("mqtt://localhost", {
  port: 5112,
  clientId: "cli_pub",
})

let num = 0;
setInterval(function (){
  client.publish("test", 
  "Hello mqtt " + (++num),
  {qos:1},
  () => console.log(num));
}, 1000)

訂閱端: sub.js

let mqtt = require("mqtt")

let client = mqtt.connect("mqtt://localhost", {
  port: 5112,
  clientId: "cli_sub",
})

client.subscribe("test",{qos:1})

client.on("message", function (topic, message) {
  console.log("received message: ", message.toString())
})

server運(yùn)行后,先啟動(dòng)sub,再啟動(dòng)pub,即可在sub中接收到推送過來的消息序列
至此實(shí)現(xiàn)了簡(jiǎn)單的即時(shí)推送

離線推送相關(guān)配置及簡(jiǎn)要介紹 離線配置-服務(wù)端:

要實(shí)現(xiàn)消息的離線推送,必然需要一個(gè)存儲(chǔ)臨時(shí)數(shù)據(jù)的部件
此處用到的是mongo,當(dāng)然可以根據(jù)需要選擇其他的存儲(chǔ)工具

server.js中的settings需更改為:

let settings = {
  port: 5112,
  persistence:{    //增加了此項(xiàng)
    factory: mosca.persistence.Mongo,
    url: "mongodb://localhost:27017/mosca"
  }
}

factory: 引入mosca對(duì)特定存儲(chǔ)工具的一些處理方法
url: 其中的 27017 為mongo所監(jiān)聽的端口號(hào),mosca為存儲(chǔ)相關(guān)數(shù)據(jù)的數(shù)據(jù)庫(kù)

值得一提的是:配置好mongo的環(huán)境后,不需要提前在mongo中手動(dòng)創(chuàng)建,若數(shù)據(jù)庫(kù)不存在會(huì)自動(dòng)生成,而且mosca會(huì)為你作好其他一切基本事項(xiàng) (即:若只想臨時(shí)體驗(yàn)下效果,甚至可以暫時(shí)把mongo放一邊 )

在mongo中,可以看到自動(dòng)新添了db: mosca
及其下的collection(相當(dāng)于關(guān)系型數(shù)據(jù)庫(kù)中的表/關(guān)系)

離線配置-客戶端:

pub.js和sub.js中的client中都可以改為:

let client = mqtt.connect("mqtt://localhost", {
  port: 5112,
  clientId: "cli_**",
  clean: false//增加了此項(xiàng)
})

clientId: 區(qū)分客戶端的識(shí)別碼
clean: 此處決定了客戶端在服務(wù)端的session是否會(huì)被清除,默認(rèn)為true,為實(shí)現(xiàn)離線推送,我們需要將其保留
clean及上文中的persistence為實(shí)現(xiàn)離線推送的關(guān)鍵配置

mqtt.connect()會(huì)返回一個(gè)mqttClient對(duì)象,包含了:reconnect(), subscribe(), publish()等一系列方法。

本文中發(fā)送端接收端被分為了pub.js和sub.js兩個(gè)獨(dú)立文件,僅僅為了方便在不同控制臺(tái)中觀察效果
一個(gè)client可以既為推送端,又為訂閱端


至此,所有代碼已完成

其他介紹:

client.subscribe():
為本客戶端訂閱一個(gè)話題,所有訂閱此話題的用戶都會(huì)收到在此話題下推送的信息

//client.subscribe(topic,opts)
client.subscribe("test",{qos:1})

opts中的qos為通信機(jī)制,控制發(fā)送端與接收端的互鎖程度
上文中的其中一個(gè)collection: subscriptions即記錄各用戶話題訂閱情況

用戶cli_sub及cli2_sub訂閱了話題test:

(新增一個(gè)cli2_pub,下文有用)

注:
重復(fù)執(zhí)行腳本sub.js實(shí)際上對(duì)topic進(jìn)行了重復(fù)訂閱
實(shí)際編碼時(shí),應(yīng)避免topic的重復(fù)訂閱,即使重復(fù)訂閱并不影響實(shí)現(xiàn)效果

client.publish():
向指定topic發(fā)送數(shù)據(jù)
message為Buffer或String格式,可以通過序列化或轉(zhuǎn)json實(shí)現(xiàn)對(duì)復(fù)雜數(shù)據(jù)對(duì)象的傳送

//client.publish(topic, message, opts, callback)
let num = 0;
setInterval(function (){
  client.publish("test", 
  "Hello mqtt " + (++num),
  {qos:1},
  () => console.log(num));
}, 1000)

參數(shù)不再贅述
此處用一個(gè)定時(shí)器定時(shí)在 topic: test 下發(fā)送"Hello mqtt 1,2,3.."

用回調(diào)函數(shù)實(shí)時(shí)打印一下發(fā)送的num:

當(dāng)訂閱者處于離線狀態(tài)時(shí),可以在collection: packets中查看到臨時(shí)數(shù)據(jù)的存儲(chǔ)情況:

mosca把每一條推送消息為所有訂閱用戶都生成了獨(dú)立的記錄,用同一個(gè)messageId進(jìn)行關(guān)聯(lián)

當(dāng)其中一個(gè)用戶(cli2_sub)上線時(shí),獲取到其對(duì)應(yīng)的數(shù)據(jù),

而后數(shù)據(jù)庫(kù)中相應(yīng)記錄便會(huì)被刪除

此時(shí)僅有cli_sub用戶的數(shù)據(jù)
當(dāng)cli2_sub上線接收消息后,packets中記錄將被清空

client.on():
即在client上觸發(fā)的事件,此處只列舉消息接收事件

//client.on(event, callback)
client.on("message", function (topic, message) {
  console.log("received message: ", message.toString())
})

處理為簡(jiǎn)單地打印到控制臺(tái)

mosca.js文檔:
https://www.npmjs.com/package...
mqtt.js文檔:
https://www.npmjs.com/package...
windows環(huán)境下mongo的配置:
https://jingyan.baidu.com/art...
及一位前輩的文章:
https://www.jianshu.com/p/831...

轉(zhuǎn)載請(qǐng)注明出處 ; )

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/19456.html

相關(guān)文章

  • 搭建IM服務(wù) so easy

    摘要:現(xiàn)在很多網(wǎng)站都通過服務(wù)來實(shí)現(xiàn)消息推送及數(shù)據(jù)即時(shí)同步功能,即時(shí)通訊組件逐漸成為產(chǎn)品的標(biāo)配。目前國(guó)內(nèi)有很多成熟穩(wěn)定的第三方即時(shí)通訊服務(wù)廠家,比如融云。 現(xiàn)在很多網(wǎng)站、APP都通過IM服務(wù)來實(shí)現(xiàn)消息推送及數(shù)據(jù)即時(shí)同步功能,即時(shí)通訊組件逐漸成為產(chǎn)品的標(biāo)配。目前國(guó)內(nèi)有很多成熟穩(wěn)定的第三方即時(shí)通訊服務(wù)廠家,比如:融云。使用這些專業(yè)的服務(wù)可以提高開發(fā)效率而且服務(wù)穩(wěn)定有保障。 如果自己DIY或者需要在...

    imccl 評(píng)論0 收藏0
  • MQTT協(xié)議(1)-簡(jiǎn)介

    摘要:,消息隊(duì)列遙測(cè)傳輸是開發(fā)的一個(gè)即時(shí)通訊協(xié)議,有可能成為物聯(lián)網(wǎng)的重要組成部分。會(huì)發(fā)生消息丟失或重復(fù)。只有一次,確保消息到達(dá)一次。此外,國(guó)內(nèi)很多企業(yè)都廣泛使用作為手機(jī)客戶端與服務(wù)器端推送消息的協(xié)議。 前幾天寫了一下MQTT協(xié)議實(shí)現(xiàn)推送數(shù)據(jù)傳輸,所以我會(huì)不定期的更新一下關(guān)注MQTT的知識(shí)。 MQTT: MQTT(Message Queuing Telemetry Transport,消息隊(duì)列...

    objc94 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<