安裝:
cnpm i vue-socket.io -S
cnpm i socket.io-client -S
客戶端:
在main.js中
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import VueSocketIO from 'vue-socket.io'
import SocketIO from "socket.io-client"
// socket 連接參數
const socketOptions = {
autoConnect: false, // 是否自動連接 如果為false在指定情況下手動觸發才連接socket,(this.$socket.open() // 開始連接socket
path: "/my-app/" // 定義socket后面的路徑,不寫默認路徑為/socket.io
)
// 注冊
Vue.use(
new VueSocketIO({
debug: true , // debug調試,生產關閉
connection: SocketIO("127.0.0.1:8080", socketOptions)
})
)
new Vue({
// 這里為全局監聽socket事件消息,不需要全局可以放到組件里面去。
sockets: {
connecting() {
console.log('正在連接')
},
disconnect() {
console.log("Socket 斷開");
},
connect_failed() {
cosnole.log('連接失敗')
},
connect() {
console.log('連接成功')
}
},
router,
store,
render: h => h(App)
}).$mount('#app')
在組件中使用
<template>
<div id="app">
<div id="nav">
<button @click="connect">連接socket</button>
<button @click="sendMessage">發送數據</button>
</div>
</div>
</template>
<script>
export default {
data() {
return {
}
},
methods:{
// 連接socket
connect() {
this.$socket.open() // 開始連接socket
// 僅在組件內訂閱事件
this.sockets.subscribe('welcome', data => {
console.log('welcome data ', data)
})
},
// 發送消息
sendMessage() {
this.$socket.emit('hello', '客戶端')
}
},
sockets:{
//
welcome: data => {
console.log('welcome data ', data)
}
}
}
</script>
客戶端使用總結
1、全局監聽
sockets:{
welcome: data => {
console.log('welcome', data)
}
}
2、組件內監聽
this.sockets.subscribe('welcome', data => {
console.log('welcome', data)
})
注意:監聽用的是this.sockets,發送消息是this.$socket
關於跨域問題:
ocket會存在跨域問題,在生產環境中vue.config.js中配置代理。實際項目中的解決方式還是后端配置跨域問題
vue.config.js配置如下
······
devServer: {
host: 'localhost',
port: 8080,
open: true, //是否自動打開瀏覽器
proxy: {
'/socket.io': {
target: 'http://172.168.10.24:8100',
ws: true,
changeOrigin: true
}
}
}
·····
訂閱事件記得要取消
socket主要還是用來寫聊天室,加入socket房間后要訂閱房間內所有的聊天內容,這時如果沒有取消之前的訂閱事件,下次進入會多次訂閱消息。也就是別人只發一條消息,你這邊接收到的卻是兩條甚至多條。哪如何取消訂閱呢,我的處理方式是在離開當前聊天頁面后,自動取消之前所有的訂閱事件。
beforeDestroy() {
this.sockets.unsubscribe(eventName)
}
同理,如果是有指定頁面才加入socket房間,退出頁面時也要記得關閉socket連接。比如你在created中開始連接socket,在beforeDestroy要記得關閉socket,不然下次進入也會連接socket。
created() {
this.$socket.open()
// 查看socket是否連接成功
this.$socket.connected
}
beforeDestroy() {
this.$socket.close()
}
node服務端參考代碼
var http = require('http'); var io = require('socket.io'); // 創建server服務 var server = http.createServer(function (req, res) { // 配置socket跨域 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(); }); // 啟動服務器 監聽 1024 端口 server.listen(1024,function() { console.log('server runing at 127.0.0.1:1024') }) // 啟動socket服務 var socket = io.listen(server, {origins: '*:*'}); // 監聽客戶端連接 socket.on('connection',function(socket) { console.log('客戶端有連接') // 監聽客戶端斷開 socket.on('disconnect', () => { console.log('客戶端斷開') }) // 給客戶端發送消息 socket.emit('welcome','歡迎連接socket') // 監聽客戶端消息 socket.on('hello', data => { console.log('接收客戶端發送數據', data) }) });
