安装:
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)
})
});
浙公网安备 33010602011771号