完整版聊天室正在更新中,欢迎大家交流:https://www.jianshu.com/p/47c221ccd393
Socket.io的默认事件列表
服务端事件
事件名称 | 描述 |
---|---|
connection | socket连接成功之后触发,用于初始化 |
message | 客户端通过socket.send来传送消息时触发此事件 |
anything | 收到任何事件时触发 |
disconnect | socket失去连接时触发 |
客户端事件
事件名称 | 描述 |
---|---|
connect | 连接成功 |
connecting | 正在连接 |
disconnect | 断开连接 |
connect_failed | 连接失败 |
error | 错误发生,并且无法被其他事件类型所处理 |
message | 同服务器端message事件 |
anything | 同服务器端anything事件 |
reconnect_failed | 重连失败 |
reconnect | 成功重连 |
reconnecting | 正在重连 |
依赖引入
前端依赖
npm i vue-socket.io -S
npm i socket.io-client -S
npm i element-ui -S
后端依赖
npm i express -S
npm i socket.io -S
前端代码
main.js
import Vue from 'vue'
import App from './App.vue'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css';
import VueSocketIO from 'vue-socket.io';
import SocketIO from 'socket.io-client'
Vue.config.productionTip = false
Vue.use(ElementUI)
Vue.use(new VueSocketIO({
debug: true,
connection: SocketIO('ws://localhost:3000')
}))
new Vue({
render: h => h(App),
}).$mount('#app')
Chat.vue
<template>
<div class="main">
<el-row>
<el-col :span="16">
<el-input id='input' v-model="input"></el-input>
</el-col>
<el-col :span="8">
<el-button type="primary" @click="sendMsg">Send</el-button>
</el-col>
</el-row>
<div id="content"></div>
</div>
</template>
<script>
const ENTER = 0
const LEAVE = 1
export default {
name: 'Chat',
data() {
return {
input: '',
content: '',
message: ''
}
},
sockets: {
connect() {
this.$message({
message: '连接成功!!!',
type: 'success'
});
},
disconnect() {
this.$message({
message: '连接断开!!!',
type: 'error'
})
},
broadcast_msg(data) {
var content = document.querySelector('#content')
var div = document.createElement('div')
div.innerText = `${data.msg} ---${data.time}`
if (data.type === ENTER) {
div.style.color = 'green'
} else if (data.type === LEAVE) {
div.style.color = 'red'
} else {
div.style.color = 'blue'
}
content.appendChild(div)
}
},
methods: {
sendMsg() {
this.$socket.emit('send_msg', this.input)
}
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.main {
width: 500px;
}
#input {
width: 10px;
}
#content {
margin-top: 15px;
text-align: left;
}
</style>
后端代码
app.js (添加第8-10行代码即可解决跨域问题)
const express = require('express')
const app = express()
const http = require('http')
const server = http.createServer(app)
const socketIO = require('socket.io')
const io = socketIO(server, {
cors: {
origin: '*'
}
});
const ENTER = 0
const LEAVE = 1
const MESSAGE = 2
let count = 0
io.on('connection', socket => {
console.log('user connected')
count++
let user = `用户${count}`
io.sockets.emit('broadcast_msg',
{
type: ENTER,
msg: `${user}加入群聊`,
time: new Date().toLocaleString()
}
)
socket.on('send_msg', (data) => {
console.log(`收到客户端的消息:${data}`)
io.sockets.emit('broadcast_msg', {
type: MESSAGE,
msg: `${user}:${data}`,
time: new Date().toLocaleString()
})
})
socket.on('disconnect', () => {
console.log('user disconnected')
io.sockets.emit('broadcast_msg', {
type: LEAVE,
msg: `${user}离开了群聊`,
time: new Date().toLocaleString()
})
count--
});
});
server.listen(3000, () => {
console.log("server running on port 3000")
})