1、下载相关的包
node使用:socket.io
vue使用:vue-socket.io和socket.io-client
2、解决跨域的问题
3、在客户端和服务端注册、监听、触发事件
4、广播实现群组交流
一、配置环境
1、服务端(node)
npm install socket.io --save
- 创建socket.js文件
let socketio = {}
let socket_io = require('socket.io')
// 获取io
socketio.getSocketio = function(server) {
//这一段是用于解决跨域问题
let io = socket_io(server, {
cors: {
origin: '*'
}
})
module.exports = socketio
- 在 bin/www.js 中引入
let http = require('http')
let app = require('../app')
let io = require('../public/socket/mysocket')
let server = http.createServer(app)
//注意要在创建服务之后再使用socket.js中暴露的方法
io.getSocketio(server)
2、客户端(vue)
npm install vue-socket.io --save
npm install socket.io-client --save
- 在main.js中引入
import VueSocketIO from 'vue-socket.io'
import SocketIO from 'socket.io-client'
Vue.use(new VueSocketIO({
debug: true,
// 服务器端地址
connection: SocketIO('ws://127.0.0.1:3000'),
// options: { path: '/node' },
vuex: {
}
}))
- 在组件中使用socket
sockets: {
connect: function() { // 这里是监听connect事件
console.log('this.$socket.id', this.$socket.id)
}
}
二、解决跨域问题
1、服务端(在socket.js中加入如下代码)
let socketio = {}
let socket_io = require('socket.io')
// 获取io
socketio.getSocketio = function(server) {
//这一段是用于解决跨域问题
let io = socket_io(server, {
cors: {
origin: '*'
}
})
module.exports = socketio
2、客户端(在vue.config.js中加入如下代码)
proxy: {
//socket.io会默认添加/socket.io后缀
[process.env.VUE_APP_BASE_API + '/socket.io']: {
target: `http://127.0.0.1:3000`,
changeOrigin: true,
pathRewrite: {
[`^` + process.env.VUE_APP_BASE_API ]: ''
}
}
}
3、浏览器中的效果
-
浏览器控制台中打印出如下信息就说明已经成功连接image.png
-同时还会输出客户端已经注册的方法image.png
三、监听、触发事件
1、服务端
//监听事件
socket.on('send', (data) => {})
//触发事件
socket.emit('send', "触发send")
2、客户端
//监听事件
sockets: {
send: function(data) {}
}
//触发事件
this.$socket.emit('send', "触发事件")
四、广播实现群组交流
1、服务端
//先加入房间
socket.join('/room1')
//将信息通过broadcastMsg广播给所有已连接的人
io.to('/room1').emit('broadcastMsg', "通知")
2、客户端
//通过监听broadcastMsg方法拿到广播消息
broadcastMsg(data) {
console.log(data)
}
5、实现在线聊天室
- 服务端 socket.js文件
/*
封装socket.io,为了获取server以便监听.
*/
let socketio = {}
let socket_io = require('socket.io')
// 获取io
socketio.getSocketio = function(server) {
let io = socket_io(server, {
cors: {
origin: '*'
}
})
io.on('connection', (socket) => {
socket.on('connSuc', (data) => {
socket.join('/kf7')
io.to('/kf7').emit('broadcastMsg', data.name)
})
socket.on('send', (data) => {
io.to('/kf7').emit('send', data)
})
})
}
module.exports = socketio
- 客户端 chat.vue
<template>
<div class="attendlist_wrap">
<van-sticky>
<van-nav-bar :title="$route.meta.title+' ('+txt+') '" />
</van-sticky>
<p class="allPeople">当前在线成员: {{ allPeople }}</p>
<div v-for="(item,index) in msgArr" :key="index">
<div class="msgCard">
<p :class="['name',item.type=='recv'?'':'recv']">{{ item.name }}</p>
<div :class="['con',item.type=='recv'?'':'recv']">
<p class="msg">{{ item.msg }}</p>
</div>
</div>
</div>
<div class="botIpt">
<van-field
v-model="sendMsg"
center
clearable
placeholder=""
>
<template #button>
<van-button class="sendBtn" size="small" type="primary" @click="sendClick"> 发送 </van-button>
</template>
</van-field>
</div>
</div>
</template>
<script>
import { changePsd, getUserInfo } from '@/api/my'
// import { monthFilter } from '@/utils/session'
import { Toast } from 'vant'
import { setInfo, getInfo } from '@/utils/session'
// import { mapGetters } from 'vuex'
export default {
data() {
return {
connStatus: 0,
txt: '未连接...',
allPeople: '',
sendMsg: '',
msgArr: [
// { type: 'send', name: '刘菲', msg: '今天又变仙女了' },
// { type: 'recv', name: '杨米', msg: '凡尔赛凡尔赛' }
]
}
},
sockets: {
connect: function() { // 这里是监听connect事件
let info = {
socketid: this.$socket.id,
username: getInfo('username'),
name: getInfo('nickname'),
msg: '连接成功'
}
this.txt = '已连接...'
this.$socket.emit('connSuc', info)
},
broadcastMsg(data) {
this.$notify({
message: data + '上线了!',
color: '#07c160',
background: '#fff',
duration: 500
})
},
disconnect() {
this.txt = '未连接...'
console.log(getInfo('username') + '断开连接')
},
send(data) {
if (data.name == getInfo('nickname')) {
data.type = 'send'
} else {
data.type = 'recv'
}
this.msgArr.push(data)
},
},
methods: {
sendClick() {
let sendObj = {
type: 'send',
name: getInfo('nickname'),
msg: this.sendMsg
}
this.sendMsg = ''
this.$socket.emit('send', sendObj)
}
}
}
</script>
<style lang="scss" scoped>
.attendlist_wrap{
width:100%;
height: 93.2vh;
margin-bottom: 50px;
background-color: #fafafa;
position: relative;
.allPeople{
text-align: center;
margin: 10px auto;
}
.msgCard{
margin: 15px;
margin-bottom: 0;
.name{
margin-bottom: 5px;
margin-left: 5px;
&.recv{
text-align: right;
margin-right: 5px;
}
}
.con{
display: flex;
justify-content: flex-start;
.msg{
width: fit-content;
height: fit-content;
padding: 10px;
font-size: 14px;
border: 1px solid #07c160;
border-radius: 10px;
box-sizing: border-box;
}
&.recv{
justify-content: flex-end;
}
}
}
.botIpt{
width:100%;
height:60px;
position: fixed;
bottom: 60px;
left: 0;
.sendBtn{
width: 70px;
letter-spacing: 1px;
}
}
}
</style>