WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。
实现目标: 在客户端发送消息给服务端时,服务端能够主动向客户端推送消息
前端: vue.js + vue-socket.io
服务端: node.js + egg.js + egg-socket.io
如果大家想拿新的服务端项目和前端项目测试,我这里有重新快速搭建,也是为了websocket学习搭建的,可看 从0开始用node.js创建一个服务端项目以及接口调用
前端代码
1安装包
npm i vue-socket.io --save
我目前使用的版本号为:
"vue-socket.io": "^3.0.10"
2.在main.js种引入
import Vue from 'vue'
import App from './App.vue'
Vue.config.productionTip = false
import VueSocketio from 'vue-socket.io' // 先将VueSocketio包引入进来
Vue.use(new VueSocketio({
debug: true,
connection: 'http://127.0.0.1:7001/',
})) // 然后注册到vue里面去
new Vue({
render: h => h(App),
sockets: { //这里的意思就是把socket挂载到vue的this上,
//让每个页面都可以通过this.$socket去调用插件里面的方法
connect: function () {
console.log('连接上');
},
res: function (val) {
console.log('接收到', val);
}
}
}).$mount('#app')
这里的对应的是服务器地址:http://127.0.0.1:7001/
3.在vue组件里面使用
<div @click="sendMsg">我点击发送消息吧</div>
sendMsg() {
this.$socket.emit('chat', '客户端向服务端发送的msg')
},
记住哦,配置好上面的,只要你npm run serve也就是启动vue项目,就应该是自动开启了websocket
你可能搜索到很多很火的文章,发现他们只这么注册到vue里面去的,然后你发现根本连接不上,他们的版本号必须安装是npm install vue-socket.io@2.1.1 --save,所以你不指定版本号我这样写就可以,毕竟新的包可能更加完善
Vue.use(VueSocketio, 'http://127.0.0.1:7001/');
服务端代码
可以看egg.js的Socket.IO 我的目录结构
我这个项目是egg.js的哦~就是用egg.js里面提供的
1.安装包
npm i egg-socket.io --save
2.将egg的插件socket.io注册到egg中
io: {
enable: true,
package: 'egg-socket.io',
},
3.配置
在config/config.default.js里面的userConfig对象里面写入
// socket.io 配置项
io: {
namespace: {
'/': {
connectionMiddleware: [ 'auth' ],
packetMiddleware: [ 'filter' ],
},
},
},
上面有两个中间件,一个是auth,主要是提示用户连接与断开的,连接成功的消息发送到客户端,断开连接的消息在服务端打印,另一个是filter将接收到的数据再发送给客户端
auth.js
'use strict'
// app/io/middlewware/auth.js
// 这个中间件的作用是提示用户连接与断开的,连接成功的消息发送到客户端,断开连接的消息在服务端打印
module.exports = app => {
return function* (next) {
this.socket.emit('res', 'connected!')
yield* next
console.log('disconnection!')
}
}
filter
'use strict'
// app/io/middleware/filter.js
// 这个中间件的作用是将接收到的数据再发送给客户端
module.exports = app => {
return function* (next) {
this.socket.emit('res', 'packet received!')
console.log('packet:', this.packet)
yield* next
}
}
4路由与文件
io.of('/').route('chat', io.controller.chat) // websocket
这里的chat只是服务端规定一个标志,客户端发消息时带上这个标志,我将他看成一个key或者事件名
io.controller.chat表示的是app文件底下的io文件底下的controller文件底下的chat.js文件,因为这里将io建立了单独的controller
chat.js内容
'use strict'
module.exports = app => {
return function* () {
const self = this
const message = this.args[0]
console.log('chat 控制器打印', message)
this.socket.emit('res', `Hi! I've got your message: ${message}`)
}
}
效果
参考: vue-socket.io 及 egg-socket.io 的简单使用
如果你对websocket感兴趣,可以关注我,接下来我应该会一篇公司项目在用的聊天室相关代码