vue中使用vue-socket.io的一些心得市咽、踩坑記錄

前言

vue項(xiàng)目中有使用到socket長(zhǎng)連接,之前一直都是都是使用vue-socke.io[github地址]抵蚊,但最近在使用時(shí)施绎,出了一些莫名奇妙的bug,也是為此掉了不少頭發(fā)贞绳,最后還是解決了谷醉。關(guān)于socket相關(guān)內(nèi)容介紹以及使用場(chǎng)景,這里不會(huì)做太多介紹(主要是懶)冈闭,可以翻看其他文章俱尼。本文主要介紹如何使用,以及再使用時(shí)需要注意一些什么萎攒。關(guān)于文章中使用的代碼遇八,我放上github地址臭猜。前端小鳥(niǎo)一枚,立誓要成為前端菜鳥(niǎo)押蚤,不足地方留言指出蔑歌,小子謝過(guò)。

安裝

這里我們安裝vue.socket.io模塊和socket.io-client模塊揽碘,也可以不用socket.io-client模塊次屠,請(qǐng)往下看。

cnpm i vue-socket.io -S
cnpm i socket.io-client -S

yarn vue-socket.io
yarn i socket.io-client

vue 客戶端使用

  • 使用socket.io-client連接
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import VueSocketIO from 'vue-socket.io'
import SocketIO from "socket.io-client"

Vue.config.productionTip = false

// socket 連接參數(shù)
const socketOptions = {
  autoConnect: false,       // 自動(dòng)連接     這里為我項(xiàng)目需求  需要在指定情況下才連接socket
}

// 注冊(cè)
Vue.use(
  new VueSocketIO({
    debug: true ,   // debug調(diào)試雳刺,生產(chǎn)建議關(guān)閉
    connection: SocketIO("127.0.0.1:1024", socketOptions),
    store,          // 如果沒(méi)有使用到store可以不用寫(xiě)
  })
)


new Vue({
  // 這里為全局監(jiān)聽(tīng)socket事件消息劫灶,監(jiān)聽(tīng)函數(shù)這里只寫(xiě)了一點(diǎn),其實(shí)很有很多事件掖桦。
  sockets: {
    connecting() {
      console.log('正在連接')
    },
    disconnect() {
      console.log("Socket 斷開(kāi)");
    },
    connect_failed() {
      cosnole.log('連接失敗')
    },
    connect() {
      console.log('socket connected')
    }
  },
  router,
  store,
  render: h => h(App)
}).$mount('#app')
  • 字符串連接

    如果是正常使用本昏,項(xiàng)目啟動(dòng)就連接socket,可以不需要加載socket.io-client模塊枪汪,直接使用涌穆。

// 注冊(cè)
Vue.use(
  new VueSocketIO({
    debug: true ,   // debug調(diào)試,生產(chǎn)建議關(guān)閉
    connection: 127.0.0.1:1024,
    store,          // 如果沒(méi)有使用到store可以不用寫(xiě)
  })
)
  • 組件中使用

<template>
  <div id="app">
    <div id="nav">
      <button @click="connect">連接socket</button>
      <button @click="sendMessage">發(fā)送數(shù)據(jù)</button>
    </div>
  </div>
</template>


<script>
export default {
  data() {
    return {

    }
  },

  methods:{

    // 連接socket
    connect() {

      this.$socket.open()       // 開(kāi)始連接socket
     
      // 訂閱事件
      this.sockets.subscribe('welcome', data => {
        console.log('welcome data ', data)
      }) 
      
    },

    // 發(fā)送消息
    sendMessage() {
      
      this.$socket.emit('hello', '這里是客戶端')

    }



  },

  sockets:{
    // 
    welcome: data => {
      console.log('welcome data ', data)
    }

  }
}
</script>

客戶端使用總結(jié)

客戶端自帶監(jiān)聽(tīng)事件

  • connect:連接成功
  • connecting:正在連接
  • disconnect:斷開(kāi)連接
  • connect_failed:連接失敗
  • error:錯(cuò)誤發(fā)生雀久,并且無(wú)法被其他事件類(lèi)型所處理
  • reconnect_failed:重連失敗
  • reconnect:成功重連
  • reconnecting:正在重連

監(jiān)聽(tīng)自定義事件

  • 全局監(jiān)聽(tīng)
sockets:{
    welcome: data => {
        console.log('welcome data', data)
    }
}
  • 組件內(nèi)監(jiān)聽(tīng)
this.sockets.subscribe('welcome', data => {
    console.log('welcome', data)
})

發(fā)送消息

注意:監(jiān)聽(tīng)用的是this.sockets宿稀,發(fā)送消息是this.$socket,不要弄混赖捌。

this.$socket.emit('hello', '這里是客戶端')

關(guān)于跨域問(wèn)題

socket會(huì)存在跨域問(wèn)題祝沸,之前看文章又說(shuō)到在vue.config.js中配置代理,差不多和后臺(tái)接口代理配置一樣越庇,但我試過(guò)好像沒(méi)啥鳥(niǎo)用罩锐,如果有知道的同學(xué)麻煩留言告訴一聲,實(shí)際項(xiàng)目中的解決方式還是后端配置跨域問(wèn)題卤唉。

服務(wù)端使用

這里為啥要講服務(wù)端使用涩惑,主要是為了讓同學(xué)更好的體驗(yàn)socket,其次是為了引出后面的bug搬味,也是一個(gè)擴(kuò)展知識(shí)把境氢,是不是覺(jué)得自己賺了??。本地開(kāi)啟socket服務(wù)可以更好的進(jìn)行調(diào)試碰纬。服務(wù)端主要還是使用node萍聊,畢竟咱也不會(huì)java、python....悦析,這里以及配置了socket跨域寿桨。

/*
 * @Descripttion: 
 * @version: 
 * @Author: fanliu
 * @Date: 2020-06-19 18:22
 * @LastEditors: fanliu
 * @LastEditTime: 2020-06-19 18:30
 */

var http = require('http');
var io = require('socket.io');

// 創(chuàng)建server服務(wù)
var server = http.createServer(function (req, res) {

  var headers = {};
  headers["Access-Control-Allow-Origin"] = "*";
  headers["Access-Control-Allow-Methods"] = "POST, GET, PUT, DELETE, OPTIONS";
  headers["Access-Control-Allow-Credentials"] = true;
  headers["Access-Control-Max-Age"] = '86400'; // 24 hours
  headers["Access-Control-Allow-Headers"] = "X-Requested-With, Access-Control-Allow-Origin, X-HTTP-Method-Override, Content-Type, Authorization, Accept";
  res.writeHead(200, headers);
  res.end();
});

// 啟動(dòng)服務(wù)器  監(jiān)聽(tīng) 1024 端口
server.listen(1024,function() {
    console.log('server runing at 127.0.0.1:1024')
})

// 啟動(dòng)socket服務(wù)
var socket = io.listen(server, {origins: '*:*'});

// 監(jiān)聽(tīng)客戶端連接
socket.on('connection',function(socket) {
    console.log('客戶端有連接')
    
    // 監(jiān)聽(tīng)客戶端斷開(kāi)
    socket.on('disconnect', () => {
        console.log('客戶端斷開(kāi)')
    })
    
    // 給客戶端發(fā)送消息
    socket.emit('welcome','歡迎連接socket')
    
        // 監(jiān)聽(tīng)客戶端消息
        socket.on('hello', data => {
            console.log('接收客戶端發(fā)送數(shù)據(jù)', data)
        })

});

服務(wù)端總結(jié)

服務(wù)端接收和發(fā)送消息和客戶端對(duì)調(diào)的,客戶端emit發(fā)送消息,那么服務(wù)端這里就要on監(jiān)聽(tīng)客戶端發(fā)送的消息亭螟,服務(wù)的發(fā)送同理挡鞍。

踩坑

訂閱事件記得要取消

socket主要還是用來(lái)寫(xiě)聊天室,加入socket房間后要訂閱房間內(nèi)所有的聊天內(nèi)容预烙,這時(shí)如果沒(méi)有取消之前的訂閱事件墨微,下次進(jìn)入會(huì)多次訂閱消息。也就是別人只發(fā)一條消息扁掸,你這邊接收到的卻是兩條甚至多條翘县。哪如何取消訂閱呢,我的處理方式是在離開(kāi)當(dāng)前聊天頁(yè)面后谴分,自動(dòng)取消之前所有的訂閱事件锈麸。

    beforeDestroy() {
        this.sockets.unsubscribe(eventName)
    }

同理,如果是有指定頁(yè)面才加入socket房間牺蹄,退出頁(yè)面時(shí)也要記得關(guān)閉socket連接忘伞。比如你在created中開(kāi)始連接socket,在beforeDestroy要記得關(guān)閉socket沙兰,不然下次進(jìn)入也會(huì)連接socket氓奈。

created() {
    this.$socket.open()
    // 查看socket是否連接成功
    this.$socket.connected
}
beforeDestroy() {
    this.$socket.close()
}

Type Error: this.sockets.subscribe is not a function

這是我最近遇到的問(wèn)題,原本以為是自己的this指向有問(wèn)題僧凰,然后從到尾查遍了整個(gè)邏輯this探颈,發(fā)現(xiàn)并不是這個(gè)問(wèn)題。

image

在打印this.sockets之后我發(fā)現(xiàn)問(wèn)題

image

subscribe訂閱事件并沒(méi)有直接存在训措,而是某個(gè)對(duì)象的屬性,于是嘗試了一下this.sockets.listenner.subscribe發(fā)現(xiàn)能用了光羞。

你以為這就結(jié)束了绩鸣??纱兑?接著我又發(fā)現(xiàn)問(wèn)題

  sockets:{

    welcome: data => {
      console.log('welcome data ', data)
    }

  }

并且訂閱的事件中呀闻,socket日志顯示component: undefined沒(méi)有看到數(shù)據(jù)

全局的訂閱事件沒(méi)有生效,并且socket自帶的連接事件也沒(méi)有啟動(dòng)打印潜慎。我直接傻了??捡多,之前使用的時(shí)候還沒(méi)有這些問(wèn)題,百度一大堆無(wú)果后铐炫,開(kāi)始像官方求助垒手。于是找到了問(wèn)題。
Vue-Socket.io: #connect subscribe, component: undefined

image

大概的意思是說(shuō)倒信,出現(xiàn)問(wèn)題的都是3.0.9的版本科贬,將版本后可以解決這個(gè)問(wèn)題。這也是我為啥要把socket服務(wù)端寫(xiě)進(jìn)了的原因鳖悠。自己本地寫(xiě)了一個(gè)小demo后榜掌,還真的是版本的問(wèn)題优妙,隨后就有了這篇文章。

總結(jié)

同學(xué)們?cè)谑褂胿ue-socket.io時(shí)要注意一下版本憎账,現(xiàn)在的3.0.9多多少少會(huì)出現(xiàn)問(wèn)題套硼,可以選擇3.0.7版本。這個(gè)可以使用文章開(kāi)頭我的測(cè)試demo進(jìn)行查看胞皱,socket服務(wù)代碼也在項(xiàng)目中熟菲。
第一次在掘金中發(fā)表文章,表達(dá)有錯(cuò)誤的地方還請(qǐng)多多諒解朴恳,之后也會(huì)發(fā)布更多前端技術(shù)文章抄罕,還請(qǐng)多多關(guān)注。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末于颖,一起剝皮案震驚了整個(gè)濱河市呆贿,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌森渐,老刑警劉巖做入,帶你破解...
    沈念sama閱讀 206,839評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異同衣,居然都是意外死亡竟块,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)耐齐,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)浪秘,“玉大人,你說(shuō)我怎么就攤上這事埠况∷市” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 153,116評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵辕翰,是天一觀的道長(zhǎng)夺衍。 經(jīng)常有香客問(wèn)我,道長(zhǎng)喜命,這世上最難降的妖魔是什么沟沙? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,371評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮壁榕,結(jié)果婚禮上矛紫,老公的妹妹穿的比我還像新娘。我一直安慰自己护桦,他們只是感情好含衔,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,384評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般贪染。 火紅的嫁衣襯著肌膚如雪缓呛。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,111評(píng)論 1 285
  • 那天杭隙,我揣著相機(jī)與錄音哟绊,去河邊找鬼。 笑死痰憎,一個(gè)胖子當(dāng)著我的面吹牛票髓,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播铣耘,決...
    沈念sama閱讀 38,416評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼洽沟,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了蜗细?” 一聲冷哼從身側(cè)響起裆操,我...
    開(kāi)封第一講書(shū)人閱讀 37,053評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎炉媒,沒(méi)想到半個(gè)月后踪区,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,558評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡吊骤,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,007評(píng)論 2 325
  • 正文 我和宋清朗相戀三年缎岗,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片白粉。...
    茶點(diǎn)故事閱讀 38,117評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡传泊,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出蜗元,到底是詐尸還是另有隱情或渤,我是刑警寧澤,帶...
    沈念sama閱讀 33,756評(píng)論 4 324
  • 正文 年R本政府宣布奕扣,位于F島的核電站,受9級(jí)特大地震影響掌敬,放射性物質(zhì)發(fā)生泄漏惯豆。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,324評(píng)論 3 307
  • 文/蒙蒙 一奔害、第九天 我趴在偏房一處隱蔽的房頂上張望楷兽。 院中可真熱鬧,春花似錦华临、人聲如沸芯杀。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,315評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)揭厚。三九已至却特,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間筛圆,已是汗流浹背裂明。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,539評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留太援,地道東北人闽晦。 一個(gè)月前我還...
    沈念sama閱讀 45,578評(píng)論 2 355
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像提岔,于是被迫代替她去往敵國(guó)和親仙蛉。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,877評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容